pax_global_header00006660000000000000000000000064133166305150014515gustar00rootroot0000000000000052 comment=aed64a2e82035f740f457e1f377d794e1eab4c75 xoreos-tools-0.0.5/000077500000000000000000000000001331663051500141745ustar00rootroot00000000000000xoreos-tools-0.0.5/.gitignore000066400000000000000000000034051331663051500161660ustar00rootroot00000000000000# Editor temp files .sw[po] .*.sw[po] *~ # MSVC files Debug/ Release/ ipch/ *.suo *.sdf *.opensdf # Build files *.[oa] *.l[oa] *.d .dirstamp .libs/ .deps/ # autotools temp files Makefile Makefile.in /INSTALL /aclocal.m4 /autom4te.cache/ /build-aux/ /config.h /config.h.in /config.log /config.status /configure /libtool /m4/libtool.m4 /m4/ltoptions.m4 /m4/ltsugar.m4 /m4/ltversion.m4 /m4/lt~obsolete.m4 /m4/pkg.m4 /stamp-h1 # CMake temp file /CMakeCache.txt /CMakeFiles/ /cmake_install.cmake /src/rules.mk.cmake /bin/ /tests/rules.mk.cmake /CTestTestfile.cmake /Testing/ # Eclipse project files /.autotools /.cproject /.project /.settings # Netbeans project files /nbproject/ # CLion project files /.idea/ # Debian temp files /debian /dists/debian/autoreconf.after /dists/debian/autoreconf.before /dists/debian/files /dists/debian/xoreos-tools.debhelper.log /dists/debian/xoreos-tools.substvars /dists/debian/xoreos-tools/ # git versioning stamp /src/version/gitstamp # Unit tests /test-suite.log /tests/common/testfile_* /tests/common/test_* /tests/aurora/test_* /tests/images/test_* /tests/xml/test_* # Unix binaries /src/gff2xml /src/tlk2xml /src/ssf2xml /src/xml2tlk /src/xml2ssf /src/convert2da /src/fixpremiumgff /src/unerf /src/unherf /src/unrim /src/unkeybif /src/unnds /src/unnsbtx /src/desmall /src/xoreostex2tga /src/nbfs2tga /src/ncgr2tga /src/cbgt2tga /src/cdpth2tga /src/ncsdis /src/erf # Windows binaries /src/gff2xml.exe /src/tlk2xml.exe /src/ssf2xml.exe /src/xml2tlk.exe /src/xml2ssf.exe /src/convert2da.exe /src/fixpremiumgff.exe /src/unerf.exe /src/unherf.exe /src/unrim.exe /src/unkeybif.exe /src/unnds.exe /src/unnsbtx.exe /src/desmall.exe /src/xoreostex2tga.exe /src/nbfs2tga.exe /src/ncgr2tga.exe /src/cbgt2tga.exe /src/cdpth2tga.exe /src/ncsdis.exe /src/erf.exe xoreos-tools-0.0.5/.travis.yml000066400000000000000000000065421331663051500163140ustar00rootroot00000000000000sudo: required dist: trusty language: cpp compiler: - gcc - clang os: - linux - osx env: global: # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created # via the "travis encrypt" command using the project repo's public key - secure: "PY2nEbgPiLlKzs5bojGmDE1KFjTQws504ZoEBh3O9AAJWfkEMQvhwfkO6wfp3hYXsQ4fZUfJM03CsJFxXiGk1oxXqBQ/lB1eKhf7GN8AY2giD+Ei6dD3hKbUwlmsbCk1YXryWsffrGwY/++0sRkgcYqAKHvQ1Z5POTNHNGMcg9M=" - coverity_scan_run_condition='\( "$CC" = "gcc" \) -a \( $USECMAKE -eq 0 \) -a \( "$TRAVIS_OS_NAME" = "linux" \)' - coverity_scan_script_test_mode=false # Various conditions where the Travis CI scripts should behave differently - is_coverity_branch='\( "$TRAVIS_BRANCH" = "coverity_scan" \)' - is_valid_config='\( ! '"$is_coverity_branch"' \) -o \( '"$coverity_scan_run_condition"' \)' - is_valid_osx='\( "$TRAVIS_OS_NAME" = "osx" \) -a \( '"$is_valid_config"' \)' - is_valid_linux='\( "$TRAVIS_OS_NAME" = "linux" \) -a \( '"$is_valid_config"' \)' - is_notcoverity_autot='\( ! '"$is_coverity_branch"' \) -a \( $USECMAKE -eq 0 \)' - is_notcoverity_cmake='\( ! '"$is_coverity_branch"' \) -a \( $USECMAKE -eq 1 \)' matrix: # Let's test both our autoconf and CMake build system - USECMAKE=0 - USECMAKE=1 matrix: exclude: # On Linux, we only need to test one compiler with both autools and CMake. # This gives us three builds on Linux: autotools+gcc, autotools+clang, CMake+gcc - compiler: clang os: linux env: USECMAKE=1 # On macOS, gcc is deprecated, so we only build with clang there. # This gives us two builds on macOS: autotools+clang, CMake+clang - compiler: gcc os: osx before_install: # Installing macOS dependencies, using brew - if eval [ $is_valid_osx ]; then brew install zlib xz libxml2; fi # Installing Linux dependencies, using apt-get - if eval [ $is_valid_linux ]; then sudo apt-get update -qq; fi - if eval [ $is_valid_linux ]; then sudo apt-get -qq install libboost-all-dev libxml2-dev; fi script: # autotools build system: ./autogen.sh && ./configure && make && make check - if eval [ $is_notcoverity_autot ]; then ./autogen.sh; fi - if eval [ $is_notcoverity_autot ]; then ./configure || cat config.log; fi - if eval [ $is_notcoverity_autot ]; then make -j4; fi - if eval [ $is_notcoverity_autot ]; then echo "" > test-suite.log; make -j4 check || cat test-suite.log; fi # CMake build system: cmake . && make && make check - if eval [ $is_notcoverity_cmake ]; then cmake .; fi - if eval [ $is_notcoverity_cmake ]; then make -j4; fi - if eval [ $is_notcoverity_cmake ]; then make -j4 check; fi addons: coverity_scan: build_script_url: https://raw.githubusercontent.com/$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH/.travis_coverity.sh project: name: $TRAVIS_REPO_SLUG notification_email: drmccoy@drmccoy.de build_command_prepend: "./autogen.sh && ./configure" build_command: "make -j4 check" branch_pattern: coverity_scan notifications: email: recipients: - ndbrandes@gmail.com on_success: change on_failure: always irc: channels: - secure: "l6ono4KSD0Kqy0J/OkKBxBLEzM0ZUFy+2Y9PY7yoVAeMTEv0gnlkndpLzkVebxnhq0aiKP0dqk4tQVGXq8nfaSTignWqa7LQ1WboqoDspJA6/uEMy0lazaQCU6T90m7Y8aTh8niyddgGstNkHJKJzlsBm93TMWj8qTB8ZzhmqaQ=" on_success: change on_failure: always use_notice: true xoreos-tools-0.0.5/.travis_coverity.sh000066400000000000000000000112741331663051500200470ustar00rootroot00000000000000#!/bin/sh set -e # Environment check echo -e "\033[33;1mNote: COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN are available on Project Settings page on scan.coverity.com\033[0m" [ -z "$COVERITY_SCAN_PROJECT_NAME" ] && echo "ERROR: COVERITY_SCAN_PROJECT_NAME must be set" && exit 1 [ -z "$COVERITY_SCAN_NOTIFICATION_EMAIL" ] && echo "ERROR: COVERITY_SCAN_NOTIFICATION_EMAIL must be set" && exit 1 [ -z "$COVERITY_SCAN_BRANCH_PATTERN" ] && echo "ERROR: COVERITY_SCAN_BRANCH_PATTERN must be set" && exit 1 [ -z "$COVERITY_SCAN_BUILD_COMMAND" ] && echo "ERROR: COVERITY_SCAN_BUILD_COMMAND must be set" && exit 1 [ -z "$COVERITY_SCAN_TOKEN" ] && echo "ERROR: COVERITY_SCAN_TOKEN must be set" && exit 1 PLATFORM=`uname` TOOL_ARCHIVE=/tmp/cov-analysis-${PLATFORM}.tgz TOOL_URL=https://scan.coverity.com/download/${PLATFORM} TOOL_BASE=/tmp/coverity-scan-analysis UPLOAD_URL="https://scan.coverity.com/builds" SCAN_URL="https://scan.coverity.com" # Verify Coverity Scan run condition COVERITY_SCAN_RUN_CONDITION=${coverity_scan_run_condition:-true} echo -ne "\033[33;1mTesting '${COVERITY_SCAN_RUN_CONDITION}' condition... " if eval [ $COVERITY_SCAN_RUN_CONDITION ]; then echo -e "True.\033[0m" else echo -e "False. Exit.\033[0m" exit 1 fi # Do not run on pull requests if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then echo -e "\033[33;1mINFO: Skipping Coverity Analysis: branch is a pull request.\033[0m" exit 0 fi # Verify this branch should run IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"` if [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then echo -e "\033[33;1mCoverity Scan configured to run on branch ${TRAVIS_BRANCH}\033[0m" else echo -e "\033[33;1mCoverity Scan NOT configured to run on branch ${TRAVIS_BRANCH}\033[0m" exit 1 fi # Verify upload is permitted AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted` if [ "$AUTH_RES" = "Access denied" ]; then echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m" exit 1 else AUTH=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['upload_permitted']"` if [ "$AUTH" = "true" ]; then echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m" else WHEN=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['next_upload_permitted_at']"` echo -e "\033[33;1mCoverity Scan analysis NOT authorized until $WHEN.\033[0m" exit 1 fi fi if [ ! -d $TOOL_BASE ]; then # Download Coverity Scan Analysis Tool if [ ! -e $TOOL_ARCHIVE ]; then echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m" wget -nv -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" fi # Extract Coverity Scan Analysis Tool echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m" mkdir -p $TOOL_BASE pushd $TOOL_BASE set -o pipefail ( tar xzf $TOOL_ARCHIVE 2>&1 ) | ( grep -v "Ignoring unknown extended header keyword" || true ) set +o pipefail popd fi TOOL_DIR=`find $TOOL_BASE -type d -name 'cov-analysis*'` export PATH=$TOOL_DIR/bin:$PATH # Build echo -e "\033[33;1mRunning Coverity Scan Analysis Tool...\033[0m" COV_BUILD_OPTIONS="" #COV_BUILD_OPTIONS="--return-emit-failures 8 --parse-error-threshold 85" RESULTS_DIR="cov-int" eval "${COVERITY_SCAN_BUILD_COMMAND_PREPEND}" COVERITY_UNSUPPORTED=1 cov-build --dir $RESULTS_DIR $COV_BUILD_OPTIONS $COVERITY_SCAN_BUILD_COMMAND cov-import-scm --dir $RESULTS_DIR --scm git --log $RESULTS_DIR/scm_log.txt 2>&1 # Upload results echo -e "\033[33;1mTarring Coverity Scan Analysis results...\033[0m" RESULTS_ARCHIVE=analysis-results.tgz tar czf $RESULTS_ARCHIVE $RESULTS_DIR SHA=`git rev-parse --short HEAD` VERSION_GIT=$(cat Makefile | grep PACKAGE_VERSION | sed -e 's/.* = //')+$SHA echo -e "\033[33;1mVersion: $VERSION_GIT...\033[0m" # Verify Coverity Scan script test mode if [ "$coverity_scan_script_test_mode" = true ]; then echo -e "\033[33;1mCoverity Scan configured in script test mode. Exit.\033[0m" exit 1 fi echo -e "\033[33;1mUploading Coverity Scan Analysis results...\033[0m" response=$(curl \ --silent --write-out "\n%{http_code}\n" \ --form project=$COVERITY_SCAN_PROJECT_NAME \ --form token=$COVERITY_SCAN_TOKEN \ --form email=$COVERITY_SCAN_NOTIFICATION_EMAIL \ --form file=@$RESULTS_ARCHIVE \ --form version=$SHA \ --form description="$VERSION_GIT" \ $UPLOAD_URL) status_code=$(echo "$response" | sed -n '$p') if [ "$status_code" != "201" ]; then TEXT=$(echo "$response" | sed '$d') echo -e "\033[33;1mCoverity Scan upload failed: $TEXT.\033[0m" exit 1 fi xoreos-tools-0.0.5/.uncrustifyrc000066400000000000000000002143141331663051500167420ustar00rootroot00000000000000# Uncrustify 0.60 # # General options # # The type of line endings newlines = auto # auto/lf/crlf/cr # The original size of tabs in the input input_tab_size = 4 # number # The size of tabs in the output (only used if align_with_tabs=true) output_tab_size = 4 # number # The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn) string_escape_char = 92 # number # Alternate string escape char for Pawn. Only works right before the quote char. string_escape_char2 = 0 # number # Allow interpreting '>=' and '>>=' as part of a template in 'void f(list>=val);'. # If true (default), 'assert(x<0 && y>=3)' will be broken. # Improvements to template detection may make this option obsolete. tok_split_gte = false # false/true # Control what to do with the UTF-8 BOM (recommend 'remove') utf8_bom = remove # ignore/add/remove/force # If the file contains bytes with values between 128 and 255, but is not UTF-8, then output as UTF-8 utf8_byte = false # false/true # Force the output encoding to UTF-8 utf8_force = false # false/true # # Indenting # # The number of columns to indent per level. # Usually 2, 3, 4, or 8. indent_columns = 4 # number # The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. # For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level indent_continue = 0 # number # How to use tabs when indenting code # 0=spaces only # 1=indent with tabs to brace level, align with spaces # 2=indent and align with tabs, using spaces when not on a tabstop indent_with_tabs = 1 # number # Comments that are not a brace level are indented with tabs on a tabstop. # Requires indent_with_tabs=2. If false, will use spaces. indent_cmt_with_tabs = false # false/true # Whether to indent strings broken by '\' so that they line up indent_align_string = false # false/true # The number of spaces to indent multi-line XML strings. # Requires indent_align_string=True indent_xml_string = 0 # number # Spaces to indent '{' from level indent_brace = 0 # number # Whether braces are indented to the body level indent_braces = false # false/true # Disabled indenting function braces if indent_braces is true indent_braces_no_func = false # false/true # Disabled indenting class braces if indent_braces is true indent_braces_no_class = false # false/true # Disabled indenting struct braces if indent_braces is true indent_braces_no_struct = false # false/true # Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. indent_brace_parent = false # false/true # Whether the 'namespace' body is indented indent_namespace = false # false/true # The number of spaces to indent a namespace block indent_namespace_level = 0 # number # If the body of the namespace is longer than this number, it won't be indented. # Requires indent_namespace=true. Default=0 (no limit) indent_namespace_limit = 0 # number # Whether the 'extern "C"' body is indented indent_extern = false # false/true # Whether the 'class' body is indented indent_class = true # false/true # Whether to indent the stuff after a leading class colon indent_class_colon = false # false/true # Virtual indent from the ':' for member initializers. Default is 2 indent_ctor_init_leading = 2 # number # Additional indenting for constructor initializer list indent_ctor_init = 0 # number # False=treat 'else\nif' as 'else if' for indenting purposes # True=indent the 'if' one level indent_else_if = false # false/true # Amount to indent variable declarations after a open brace. neg=relative, pos=absolute indent_var_def_blk = 0 # number # Indent continued variable declarations instead of aligning. indent_var_def_cont = false # false/true # True: force indentation of function definition to start in column 1 # False: use the default behavior indent_func_def_force_col1 = false # false/true # True: indent continued function call parameters one indent level # False: align parameters under the open paren indent_func_call_param = false # false/true # Same as indent_func_call_param, but for function defs indent_func_def_param = false # false/true # Same as indent_func_call_param, but for function protos indent_func_proto_param = false # false/true # Same as indent_func_call_param, but for class declarations indent_func_class_param = false # false/true # Same as indent_func_call_param, but for class variable constructors indent_func_ctor_var_param = false # false/true # Same as indent_func_call_param, but for templates indent_template_param = false # false/true # Double the indent for indent_func_xxx_param options indent_func_param_double = false # false/true # Indentation column for standalone 'const' function decl/proto qualifier indent_func_const = 0 # number # Indentation column for standalone 'throw' function decl/proto qualifier indent_func_throw = 0 # number # The number of spaces to indent a continued '->' or '.' # Usually set to 0, 1, or indent_columns. indent_member = 0 # number # Spaces to indent single line ('//') comments on lines before code indent_sing_line_comments = 0 # number # If set, will indent trailing single line ('//') comments relative # to the code instead of trying to keep the same absolute column indent_relative_single_line_comments = false # false/true # Spaces to indent 'case' from 'switch' # Usually 0 or indent_columns. indent_switch_case = indent_columns # number # Spaces to shift the 'case' line, without affecting any other lines # Usually 0. indent_case_shift = 0 # number # Spaces to indent '{' from 'case'. # By default, the brace will appear under the 'c' in case. # Usually set to 0 or indent_columns. indent_case_brace = 0 # number # Whether to indent comments found in first column indent_col1_comment = true # false/true # How to indent goto labels # >0 : absolute column where 1 is the leftmost column # <=0 : subtract from brace indent indent_label = 1 # number # Same as indent_label, but for access specifiers that are followed by a colon indent_access_spec = -4 # number # Indent the code after an access specifier by one level. # If set, this option forces 'indent_access_spec=0' indent_access_spec_body = false # false/true # If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended) indent_paren_nl = false # false/true # Controls the indent of a close paren after a newline. # 0: Indent to body level # 1: Align under the open paren # 2: Indent to the brace level indent_paren_close = 0 # number # Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren indent_comma_paren = false # false/true # Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren indent_bool_paren = false # false/true # If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones indent_first_bool_expr = false # false/true # If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended) indent_square_nl = false # false/true # Don't change the relative indent of ESQL/C 'EXEC SQL' bodies indent_preserve_sql = false # false/true # Align continued statements at the '='. Default=True # If FALSE or the '=' is followed by a newline, the next line is indent one tab. indent_align_assign = true # false/true # Indent OC blocks at brace level instead of usual rules. indent_oc_block = false # false/true # Indent OC blocks in a message relative to the parameter name. # 0=use indent_oc_block rules, 1+=spaces to indent indent_oc_block_msg = 0 # number # Minimum indent for subsequent parameters indent_oc_msg_colon = 0 # number # # Spacing options # # Add or remove space around arithmetic operator '+', '-', '/', '*', etc sp_arith = force # ignore/add/remove/force # Add or remove space around assignment operator '=', '+=', etc sp_assign = force # ignore/add/remove/force # Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign sp_cpp_lambda_assign = remove # ignore/add/remove/force # Add or remove space after the capture specification in C++11 lambda. sp_cpp_lambda_paren = remove # ignore/add/remove/force # Add or remove space around assignment operator '=' in a prototype sp_assign_default = ignore # ignore/add/remove/force # Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign. sp_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign. sp_after_assign = ignore # ignore/add/remove/force # Add or remove space around assignment '=' in enum sp_enum_assign = ignore # ignore/add/remove/force # Add or remove space before assignment '=' in enum. Overrides sp_enum_assign. sp_enum_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment '=' in enum. Overrides sp_enum_assign. sp_enum_after_assign = ignore # ignore/add/remove/force # Add or remove space around preprocessor '##' concatenation operator. Default=Add sp_pp_concat = force # ignore/add/remove/force # Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator. sp_pp_stringify = force # ignore/add/remove/force # Add or remove space before preprocessor '#' stringify operator as in '#define x(y) L#y'. sp_before_pp_stringify = ignore # ignore/add/remove/force # Add or remove space around boolean operators '&&' and '||' sp_bool = force # ignore/add/remove/force # Add or remove space around compare operator '<', '>', '==', etc sp_compare = force # ignore/add/remove/force # Add or remove space inside '(' and ')' sp_inside_paren = remove # ignore/add/remove/force # Add or remove space between nested parens: '((' vs ') )' sp_paren_paren = remove # ignore/add/remove/force # Add or remove space between back-to-back parens: ')(' vs ') (' sp_cparen_oparen = remove # ignore/add/remove/force # Whether to balance spaces inside nested parens sp_balance_nested_parens = false # false/true # Add or remove space between ')' and '{' sp_paren_brace = force # ignore/add/remove/force # Add or remove space before pointer star '*' sp_before_ptr_star = force # ignore/add/remove/force # Add or remove space before pointer star '*' that isn't followed by a variable name # If set to 'ignore', sp_before_ptr_star is used instead. sp_before_unnamed_ptr_star = force # ignore/add/remove/force # Add or remove space between pointer stars '*' sp_between_ptr_star = remove # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a word. sp_after_ptr_star = remove # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by a func proto/def. sp_after_ptr_star_func = remove # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by an open paren (function types). sp_ptr_star_paren = remove # ignore/add/remove/force # Add or remove space before a pointer star '*', if followed by a func proto/def. sp_before_ptr_star_func = remove # ignore/add/remove/force # Add or remove space before a reference sign '&' sp_before_byref = force # ignore/add/remove/force # Add or remove space before a reference sign '&' that isn't followed by a variable name # If set to 'ignore', sp_before_byref is used instead. sp_before_unnamed_byref = ignore # ignore/add/remove/force # Add or remove space after reference sign '&', if followed by a word. sp_after_byref = remove # ignore/add/remove/force # Add or remove space after a reference sign '&', if followed by a func proto/def. sp_after_byref_func = remove # ignore/add/remove/force # Add or remove space before a reference sign '&', if followed by a func proto/def. sp_before_byref_func = remove # ignore/add/remove/force # Add or remove space between type and word. Default=Force sp_after_type = force # ignore/add/remove/force # Add or remove space before the paren in the D constructs 'template Foo(' and 'class Foo('. sp_before_template_paren = ignore # ignore/add/remove/force # Add or remove space in 'template <' vs 'template<'. # If set to ignore, sp_before_angle is used. sp_template_angle = ignore # ignore/add/remove/force # Add or remove space before '<>' sp_before_angle = remove # ignore/add/remove/force # Add or remove space inside '<' and '>' sp_inside_angle = remove # ignore/add/remove/force # Add or remove space after '<>' sp_after_angle = force # ignore/add/remove/force # Add or remove space between '<>' and '(' as found in 'new List();' sp_angle_paren = remove # ignore/add/remove/force # Add or remove space between '<>' and a word as in 'List m;' sp_angle_word = force # ignore/add/remove/force # Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add sp_angle_shift = force # ignore/add/remove/force # Permit removal of the space between '>>' in 'foo >' (C++11 only). Default=False # sp_angle_shift cannot remove the space without this option. sp_permit_cpp11_shift = false # false/true # Add or remove space before '(' of 'if', 'for', 'switch', and 'while' sp_before_sparen = force # ignore/add/remove/force # Add or remove space inside if-condition '(' and ')' sp_inside_sparen = remove # ignore/add/remove/force # Add or remove space before if-condition ')'. Overrides sp_inside_sparen. sp_inside_sparen_close = ignore # ignore/add/remove/force # Add or remove space before if-condition '('. Overrides sp_inside_sparen. sp_inside_sparen_open = ignore # ignore/add/remove/force # Add or remove space after ')' of 'if', 'for', 'switch', and 'while' sp_after_sparen = force # ignore/add/remove/force # Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while' sp_sparen_brace = force # ignore/add/remove/force # Add or remove space between 'invariant' and '(' in the D language. sp_invariant_paren = ignore # ignore/add/remove/force # Add or remove space after the ')' in 'invariant (C) c' in the D language. sp_after_invariant_paren = ignore # ignore/add/remove/force # Add or remove space before empty statement ';' on 'if', 'for' and 'while' sp_special_semi = remove # ignore/add/remove/force # Add or remove space before ';'. Default=Remove sp_before_semi = remove # ignore/add/remove/force # Add or remove space before ';' in non-empty 'for' statements sp_before_semi_for = remove # ignore/add/remove/force # Add or remove space before a semicolon of an empty part of a for statement. sp_before_semi_for_empty = remove # ignore/add/remove/force # Add or remove space after ';', except when followed by a comment. Default=Add sp_after_semi = force # ignore/add/remove/force # Add or remove space after ';' in non-empty 'for' statements. Default=Force sp_after_semi_for = force # ignore/add/remove/force # Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; ). sp_after_semi_for_empty = remove # ignore/add/remove/force # Add or remove space before '[' (except '[]') sp_before_square = remove # ignore/add/remove/force # Add or remove space before '[]' sp_before_squares = remove # ignore/add/remove/force # Add or remove space inside a non-empty '[' and ']' sp_inside_square = remove # ignore/add/remove/force # Add or remove space after ',' sp_after_comma = force # ignore/add/remove/force # Add or remove space before ',' sp_before_comma = remove # ignore/add/remove/force # Add or remove space between an open paren and comma: '(,' vs '( ,' sp_paren_comma = remove # ignore/add/remove/force # Add or remove space before the variadic '...' when preceded by a non-punctuator sp_before_ellipsis = force # ignore/add/remove/force # Add or remove space after class ':' sp_after_class_colon = force # ignore/add/remove/force # Add or remove space before class ':' sp_before_class_colon = force # ignore/add/remove/force # Add or remove space before case ':'. Default=Remove sp_before_case_colon = remove # ignore/add/remove/force # Add or remove space between 'operator' and operator sign sp_after_operator = remove # ignore/add/remove/force # Add or remove space between the operator symbol and the open paren, as in 'operator ++(' sp_after_operator_sym = remove # ignore/add/remove/force # Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' sp_after_cast = force # ignore/add/remove/force # Add or remove spaces inside cast parens sp_inside_paren_cast = remove # ignore/add/remove/force # Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)' sp_cpp_cast_paren = remove # ignore/add/remove/force # Add or remove space between 'sizeof' and '(' sp_sizeof_paren = remove # ignore/add/remove/force # Add or remove space after the tag keyword (Pawn) sp_after_tag = force # ignore/add/remove/force # Add or remove space inside enum '{' and '}' sp_inside_braces_enum = force # ignore/add/remove/force # Add or remove space inside struct/union '{' and '}' sp_inside_braces_struct = force # ignore/add/remove/force # Add or remove space inside '{' and '}' sp_inside_braces = force # ignore/add/remove/force # Add or remove space inside '{}' sp_inside_braces_empty = remove # ignore/add/remove/force # Add or remove space between return type and function name # A minimum of 1 is forced except for pointer return types. sp_type_func = remove # ignore/add/remove/force # Add or remove space between function name and '(' on function declaration sp_func_proto_paren = remove # ignore/add/remove/force # Add or remove space between function name and '(' on function definition sp_func_def_paren = remove # ignore/add/remove/force # Add or remove space inside empty function '()' sp_inside_fparens = remove # ignore/add/remove/force # Add or remove space inside function '(' and ')' sp_inside_fparen = remove # ignore/add/remove/force # Add or remove space inside the first parens in the function type: 'void (*x)(...)' sp_inside_tparen = ignore # ignore/add/remove/force # Add or remove between the parens in the function type: 'void (*x)(...)' sp_after_tparen_close = ignore # ignore/add/remove/force # Add or remove space between ']' and '(' when part of a function call. sp_square_fparen = ignore # ignore/add/remove/force # Add or remove space between ')' and '{' of function sp_fparen_brace = force # ignore/add/remove/force # Add or remove space between function name and '(' on function calls sp_func_call_paren = ignore # ignore/add/remove/force # Add or remove space between function name and '()' on function calls without parameters. # If set to 'ignore' (the default), sp_func_call_paren is used. sp_func_call_paren_empty = ignore # ignore/add/remove/force # Add or remove space between the user function name and '(' on function calls # You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file. sp_func_call_user_paren = ignore # ignore/add/remove/force # Add or remove space between a constructor/destructor and the open paren sp_func_class_paren = remove # ignore/add/remove/force # Add or remove space between 'return' and '(' sp_return_paren = force # ignore/add/remove/force # Add or remove space between '__attribute__' and '(' sp_attribute_paren = remove # ignore/add/remove/force # Add or remove space between 'defined' and '(' in '#if defined (FOO)' sp_defined_paren = remove # ignore/add/remove/force # Add or remove space between 'throw' and '(' in 'throw (something)' sp_throw_paren = force # ignore/add/remove/force # Add or remove space between 'throw' and anything other than '(' as in '@throw [...];' sp_after_throw = ignore # ignore/add/remove/force # Add or remove space between 'catch' and '(' in 'catch (something) { }' # If set to ignore, sp_before_sparen is used. sp_catch_paren = ignore # ignore/add/remove/force # Add or remove space between 'version' and '(' in 'version (something) { }' (D language) # If set to ignore, sp_before_sparen is used. sp_version_paren = ignore # ignore/add/remove/force # Add or remove space between 'scope' and '(' in 'scope (something) { }' (D language) # If set to ignore, sp_before_sparen is used. sp_scope_paren = ignore # ignore/add/remove/force # Add or remove space between macro and value sp_macro = force # ignore/add/remove/force # Add or remove space between macro function ')' and value sp_macro_func = force # ignore/add/remove/force # Add or remove space between 'else' and '{' if on the same line sp_else_brace = force # ignore/add/remove/force # Add or remove space between '}' and 'else' if on the same line sp_brace_else = force # ignore/add/remove/force # Add or remove space between '}' and the name of a typedef on the same line sp_brace_typedef = force # ignore/add/remove/force # Add or remove space between 'catch' and '{' if on the same line sp_catch_brace = force # ignore/add/remove/force # Add or remove space between '}' and 'catch' if on the same line sp_brace_catch = force # ignore/add/remove/force # Add or remove space between 'finally' and '{' if on the same line sp_finally_brace = force # ignore/add/remove/force # Add or remove space between '}' and 'finally' if on the same line sp_brace_finally = force # ignore/add/remove/force # Add or remove space between 'try' and '{' if on the same line sp_try_brace = force # ignore/add/remove/force # Add or remove space between get/set and '{' if on the same line sp_getset_brace = force # ignore/add/remove/force # Add or remove space between a variable and '{' for C++ uniform initialization sp_word_brace = force # ignore/add/remove/force # Add or remove space between a variable and '{' for a namespace sp_word_brace_ns = force # ignore/add/remove/force # Add or remove space before the '::' operator sp_before_dc = remove # ignore/add/remove/force # Add or remove space after the '::' operator sp_after_dc = remove # ignore/add/remove/force # Add or remove around the D named array initializer ':' operator sp_d_array_colon = ignore # ignore/add/remove/force # Add or remove space after the '!' (not) operator. Default=Remove sp_not = remove # ignore/add/remove/force # Add or remove space after the '~' (invert) operator. Default=Remove sp_inv = remove # ignore/add/remove/force # Add or remove space after the '&' (address-of) operator. Default=Remove # This does not affect the spacing after a '&' that is part of a type. sp_addr = remove # ignore/add/remove/force # Add or remove space around the '.' or '->' operators. Default=Remove sp_member = remove # ignore/add/remove/force # Add or remove space after the '*' (dereference) operator. Default=Remove # This does not affect the spacing after a '*' that is part of a type. sp_deref = remove # ignore/add/remove/force # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove sp_sign = remove # ignore/add/remove/force # Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove sp_incdec = remove # ignore/add/remove/force # Add or remove space before a backslash-newline at the end of a line. Default=Add sp_before_nl_cont = add # ignore/add/remove/force # Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;' sp_after_oc_scope = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '-(int) f:(int) x;' vs '-(int) f: (int) x;' sp_after_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '-(int) f: (int) x;' vs '-(int) f : (int) x;' sp_before_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the colon in immutable dictionary expression # 'NSDictionary *test = @{@"foo" :@"bar"};' sp_after_oc_dict_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in immutable dictionary expression # 'NSDictionary *test = @{@"foo" :@"bar"};' sp_before_oc_dict_colon = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '[object setValue:1];' vs '[object setValue: 1];' sp_after_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '[object setValue:1];' vs '[object setValue :1];' sp_before_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the (type) in message specs # '-(int)f: (int) x;' vs '-(int)f: (int)x;' sp_after_oc_type = ignore # ignore/add/remove/force # Add or remove space after the first (type) in message specs # '-(int) f:(int)x;' vs '-(int)f:(int)x;' sp_after_oc_return_type = ignore # ignore/add/remove/force # Add or remove space between '@selector' and '(' # '@selector(msgName)' vs '@selector (msgName)' # Also applies to @protocol() constructs sp_after_oc_at_sel = ignore # ignore/add/remove/force # Add or remove space between '@selector(x)' and the following word # '@selector(foo) a:' vs '@selector(foo)a:' sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space inside '@selector' parens # '@selector(foo)' vs '@selector( foo )' # Also applies to @protocol() constructs sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space before a block pointer caret # '^int (int arg){...}' vs. ' ^int (int arg){...}' sp_before_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space after a block pointer caret # '^int (int arg){...}' vs. '^ int (int arg){...}' sp_after_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space between the receiver and selector in a message. # '[receiver selector ...]' sp_after_oc_msg_receiver = ignore # ignore/add/remove/force # Add or remove space after @property. sp_after_oc_property = ignore # ignore/add/remove/force # Add or remove space around the ':' in 'b ? t : f' sp_cond_colon = force # ignore/add/remove/force # Add or remove space around the '?' in 'b ? t : f' sp_cond_question = force # ignore/add/remove/force # Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here. sp_case_label = force # ignore/add/remove/force # Control the space around the D '..' operator. sp_range = ignore # ignore/add/remove/force # Control the spacing after ':' in 'for (TYPE VAR : EXPR)' (Java) sp_after_for_colon = ignore # ignore/add/remove/force # Control the spacing before ':' in 'for (TYPE VAR : EXPR)' (Java) sp_before_for_colon = ignore # ignore/add/remove/force # Control the spacing in 'extern (C)' (D) sp_extern_paren = ignore # ignore/add/remove/force # Control the space after the opening of a C++ comment '// A' vs '//A' sp_cmt_cpp_start = force # ignore/add/remove/force # Controls the spaces between #else or #endif and a trailing comment sp_endif_cmt = force # ignore/add/remove/force # Controls the spaces after 'new', 'delete', and 'delete[]' sp_after_new = force # ignore/add/remove/force # Controls the spaces before a trailing or embedded comment sp_before_tr_emb_cmt = add # ignore/add/remove/force # Number of spaces before a trailing or embedded comment sp_num_before_tr_emb_cmt = 0 # number # Control space between a Java annotation and the open paren. sp_annotation_paren = ignore # ignore/add/remove/force # # Code alignment (not left column spaces/tabs) # # Whether to keep non-indenting tabs align_keep_tabs = false # false/true # Whether to use tabs for aligning align_with_tabs = false # false/true # Whether to bump out to the next tab when aligning align_on_tabstop = false # false/true # Whether to left-align numbers align_number_left = false # false/true # Whether to keep whitespace not required for alignment. align_keep_extra_space = false # false/true # Align variable definitions in prototypes and functions align_func_params = true # false/true # Align parameters in single-line functions that have the same name. # The function names must already be aligned with each other. align_same_func_call_params = true # false/true # The span for aligning variable definitions (0=don't align) align_var_def_span = 1 # number # How to align the star in variable definitions. # 0=Part of the type 'void * foo;' # 1=Part of the variable 'void *foo;' # 2=Dangling 'void *foo;' align_var_def_star_style = 1 # number # How to align the '&' in variable definitions. # 0=Part of the type # 1=Part of the variable # 2=Dangling align_var_def_amp_style = 1 # number # The threshold for aligning variable definitions (0=no limit) align_var_def_thresh = 8 # number # The gap for aligning variable definitions align_var_def_gap = 1 # number # Whether to align the colon in struct bit fields align_var_def_colon = true # false/true # Whether to align any attribute after the variable name align_var_def_attribute = true # false/true # Whether to align inline struct/enum/union variable definitions align_var_def_inline = true # false/true # The span for aligning on '=' in assignments (0=don't align) align_assign_span = 1 # number # The threshold for aligning on '=' in assignments (0=no limit) align_assign_thresh = 8 # number # The span for aligning on '=' in enums (0=don't align) align_enum_equ_span = 1 # number # The threshold for aligning on '=' in enums (0=no limit) align_enum_equ_thresh = 8 # number # The span for aligning struct/union (0=don't align) align_var_struct_span = 1 # number # The threshold for aligning struct/union member definitions (0=no limit) align_var_struct_thresh = 8 # number # The gap for aligning struct/union member definitions align_var_struct_gap = 1 # number # The span for aligning struct initializer values (0=don't align) align_struct_init_span = 1 # number # The minimum space between the type and the synonym of a typedef align_typedef_gap = 1 # number # The span for aligning single-line typedefs (0=don't align) align_typedef_span = 1 # number # How to align typedef'd functions with other typedefs # 0: Don't mix them at all # 1: align the open paren with the types # 2: align the function type name with the other type names align_typedef_func = 0 # number # Controls the positioning of the '*' in typedefs. Just try it. # 0: Align on typedef type, ignore '*' # 1: The '*' is part of type name: typedef int *pint; # 2: The '*' is part of the type, but dangling: typedef int *pint; align_typedef_star_style = 0 # number # Controls the positioning of the '&' in typedefs. Just try it. # 0: Align on typedef type, ignore '&' # 1: The '&' is part of type name: typedef int &pint; # 2: The '&' is part of the type, but dangling: typedef int &pint; align_typedef_amp_style = 0 # number # The span for aligning comments that end lines (0=don't align) align_right_cmt_span = 1 # number # If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment align_right_cmt_mix = false # false/true # If a trailing comment is more than this number of columns away from the text it follows, # it will qualify for being aligned. This has to be > 0 to do anything. align_right_cmt_gap = 1 # number # Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore) align_right_cmt_at_col = 0 # number # The span for aligning function prototypes (0=don't align) align_func_proto_span = 1 # number # Minimum gap between the return type and the function name. align_func_proto_gap = 1 # number # Align function protos on the 'operator' keyword instead of what follows align_on_operator = false # false/true # Whether to mix aligning prototype and variable declarations. # If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. align_mix_var_proto = false # false/true # Align single-line functions with function prototypes, uses align_func_proto_span align_single_line_func = false # false/true # Aligning the open brace of single-line functions. # Requires align_single_line_func=true, uses align_func_proto_span align_single_line_brace = false # false/true # Gap for align_single_line_brace. align_single_line_brace_gap = 1 # number # The span for aligning ObjC msg spec (0=don't align) align_oc_msg_spec_span = 1 # number # Whether to align macros wrapped with a backslash and a newline. # This will not work right if the macro contains a multi-line comment. align_nl_cont = false # false/true # # Align macro functions and variables together align_pp_define_together = false # false/true # The minimum space between label and value of a preprocessor define align_pp_define_gap = 1 # number # The span for aligning on '#define' bodies (0=don't align) align_pp_define_span = 1 # number # Align lines that start with '<<' with previous '<<'. Default=true align_left_shift = true # false/true # Span for aligning parameters in an Obj-C message call on the ':' (0=don't align) align_oc_msg_colon_span = 1 # number # If true, always align with the first parameter, even if it is too short. align_oc_msg_colon_first = false # false/true # Aligning parameters in an Obj-C '+' or '-' declaration on the ':' align_oc_decl_colon = false # false/true # # Newline adding and removing options # # Whether to collapse empty blocks between '{' and '}' nl_collapse_empty_body = false # false/true # Don't split one-line braced assignments - 'foo_t f = { 1, 2 };' nl_assign_leave_one_liners = true # false/true # Don't split one-line braced statements inside a class xx { } body nl_class_leave_one_liners = true # false/true # Don't split one-line enums: 'enum foo { BAR = 15 };' nl_enum_leave_one_liners = true # false/true # Don't split one-line get or set functions nl_getset_leave_one_liners = true # false/true # Don't split one-line function definitions - 'int foo() { return 0; }' nl_func_leave_one_liners = true # false/true # Don't split one-line C++11 lambdas - '[]() { return 0; }' nl_cpp_lambda_leave_one_liners = true # false/true # Don't split one-line if/else statements - 'if(a) b++;' nl_if_leave_one_liners = false # false/true # Don't split one-line OC messages nl_oc_msg_leave_one_liner = false # false/true # Add or remove newlines at the start of the file nl_start_of_file = remove # ignore/add/remove/force # The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force' nl_start_of_file_min = 0 # number # Add or remove newline at the end of the file nl_end_of_file = force # ignore/add/remove/force # The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force') nl_end_of_file_min = 1 # number # Add or remove newline between '=' and '{' nl_assign_brace = remove # ignore/add/remove/force # Add or remove newline between '=' and '[' (D only) nl_assign_square = remove # ignore/add/remove/force # Add or remove newline after '= [' (D only). Will also affect the newline before the ']' nl_after_square_assign = ignore # ignore/add/remove/force # The number of blank lines after a block of variable definitions at the top of a function body # 0 = No change (default) nl_func_var_def_blk = 0 # number # The number of newlines before a block of typedefs # 0 = No change (default) nl_typedef_blk_start = 0 # number # The number of newlines after a block of typedefs # 0 = No change (default) nl_typedef_blk_end = 0 # number # The maximum consecutive newlines within a block of typedefs # 0 = No change (default) nl_typedef_blk_in = 0 # number # The number of newlines before a block of variable definitions not at the top of a function body # 0 = No change (default) nl_var_def_blk_start = 0 # number # The number of newlines after a block of variable definitions not at the top of a function body # 0 = No change (default) nl_var_def_blk_end = 0 # number # The maximum consecutive newlines within a block of variable definitions # 0 = No change (default) nl_var_def_blk_in = 0 # number # Add or remove newline between a function call's ')' and '{', as in: # list_for_each(item, &list) { } nl_fcall_brace = remove # ignore/add/remove/force # Add or remove newline between 'enum' and '{' nl_enum_brace = remove # ignore/add/remove/force # Add or remove newline between 'struct and '{' nl_struct_brace = remove # ignore/add/remove/force # Add or remove newline between 'union' and '{' nl_union_brace = remove # ignore/add/remove/force # Add or remove newline between 'if' and '{' nl_if_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'else' nl_brace_else = remove # ignore/add/remove/force # Add or remove newline between 'else if' and '{' # If set to ignore, nl_if_brace is used instead nl_elseif_brace = remove # ignore/add/remove/force # Add or remove newline between 'else' and '{' nl_else_brace = remove # ignore/add/remove/force # Add or remove newline between 'else' and 'if' nl_else_if = remove # ignore/add/remove/force # Add or remove newline between '}' and 'finally' nl_brace_finally = remove # ignore/add/remove/force # Add or remove newline between 'finally' and '{' nl_finally_brace = remove # ignore/add/remove/force # Add or remove newline between 'try' and '{' nl_try_brace = remove # ignore/add/remove/force # Add or remove newline between get/set and '{' nl_getset_brace = remove # ignore/add/remove/force # Add or remove newline between 'for' and '{' nl_for_brace = remove # ignore/add/remove/force # Add or remove newline between 'catch' and '{' nl_catch_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'catch' nl_brace_catch = remove # ignore/add/remove/force # Add or remove newline between 'while' and '{' nl_while_brace = remove # ignore/add/remove/force # Add or remove newline between 'scope (x)' and '{' (D) nl_scope_brace = remove # ignore/add/remove/force # Add or remove newline between 'unittest' and '{' (D) nl_unittest_brace = remove # ignore/add/remove/force # Add or remove newline between 'version (x)' and '{' (D) nl_version_brace = remove # ignore/add/remove/force # Add or remove newline between 'using' and '{' nl_using_brace = remove # ignore/add/remove/force # Add or remove newline between two open or close braces. # Due to general newline/brace handling, REMOVE may not work. nl_brace_brace = remove # ignore/add/remove/force # Add or remove newline between 'do' and '{' nl_do_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'while' of 'do' statement nl_brace_while = remove # ignore/add/remove/force # Add or remove newline between 'switch' and '{' nl_switch_brace = remove # ignore/add/remove/force # Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. # Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace. nl_multi_line_cond = false # false/true # Force a newline in a define after the macro name for multi-line defines. nl_multi_line_define = true # false/true # Whether to put a newline before 'case' statement nl_before_case = false # false/true # Add or remove newline between ')' and 'throw' nl_before_throw = ignore # ignore/add/remove/force # Whether to put a newline after 'case' statement nl_after_case = true # false/true # Add or remove a newline between a case ':' and '{'. Overrides nl_after_case. nl_case_colon_brace = remove # ignore/add/remove/force # Newline between namespace and { nl_namespace_brace = remove # ignore/add/remove/force # Add or remove newline between 'template<>' and whatever follows. nl_template_class = ignore # ignore/add/remove/force # Add or remove newline between 'class' and '{' nl_class_brace = remove # ignore/add/remove/force # Add or remove newline after each ',' in the constructor member initialization nl_class_init_args = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a function definition nl_func_type_name = remove # ignore/add/remove/force # Add or remove newline between return type and function name inside a class {} # Uses nl_func_type_name or nl_func_proto_type_name if set to ignore. nl_func_type_name_class = remove # ignore/add/remove/force # Add or remove newline between function scope and name in a definition # Controls the newline after '::' in 'void A::f() { }' nl_func_scope_name = remove # ignore/add/remove/force # Add or remove newline between return type and function name in a prototype nl_func_proto_type_name = remove # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' nl_func_paren = remove # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' in the definition nl_func_def_paren = remove # ignore/add/remove/force # Add or remove newline after '(' in a function declaration nl_func_decl_start = remove # ignore/add/remove/force # Add or remove newline after '(' in a function definition nl_func_def_start = remove # ignore/add/remove/force # Overrides nl_func_decl_start when there is only one parameter. nl_func_decl_start_single = ignore # ignore/add/remove/force # Overrides nl_func_def_start when there is only one parameter. nl_func_def_start_single = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function declaration nl_func_decl_args = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function definition nl_func_def_args = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function declaration nl_func_decl_end = remove # ignore/add/remove/force # Add or remove newline before the ')' in a function definition nl_func_def_end = remove # ignore/add/remove/force # Overrides nl_func_decl_end when there is only one parameter. nl_func_decl_end_single = ignore # ignore/add/remove/force # Overrides nl_func_def_end when there is only one parameter. nl_func_def_end_single = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function declaration. nl_func_decl_empty = remove # ignore/add/remove/force # Add or remove newline between '()' in a function definition. nl_func_def_empty = remove # ignore/add/remove/force # Whether to put each OC message parameter on a separate line # See nl_oc_msg_leave_one_liner nl_oc_msg_args = false # false/true # Add or remove newline between function signature and '{' nl_fdef_brace = remove # ignore/add/remove/force # Add or remove newline between C++11 lambda signature and '{' nl_cpp_ldef_brace = remove # ignore/add/remove/force # Add or remove a newline between the return keyword and return expression. nl_return_expr = remove # ignore/add/remove/force # Whether to put a newline after semicolons, except in 'for' statements nl_after_semicolon = true # false/true # Whether to put a newline after brace open. # This also adds a newline before the matching brace close. nl_after_brace_open = true # false/true # If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is # placed between the open brace and a trailing single-line comment. nl_after_brace_open_cmt = false # false/true # Whether to put a newline after a virtual brace open with a non-empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open = true # false/true # Whether to put a newline after a virtual brace open with an empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open_empty = true # false/true # Whether to put a newline after a brace close. # Does not apply if followed by a necessary ';'. nl_after_brace_close = false # false/true # Whether to put a newline after a virtual brace close. # Would add a newline before return in: 'if (foo) a++; return;' nl_after_vbrace_close = true # false/true # Control the newline between the close brace and 'b' in: 'struct { int a; } b;' # Affects enums, unions, and structures. If set to ignore, uses nl_after_brace_close nl_brace_struct_var = ignore # ignore/add/remove/force # Whether to alter newlines in '#define' macros nl_define_macro = true # false/true # Whether to not put blanks after '#ifxx', '#elxx', or before '#endif' nl_squeeze_ifdef = false # false/true # Add or remove blank line before 'if' nl_before_if = ignore # ignore/add/remove/force # Add or remove blank line after 'if' statement nl_after_if = ignore # ignore/add/remove/force # Add or remove blank line before 'for' nl_before_for = ignore # ignore/add/remove/force # Add or remove blank line after 'for' statement nl_after_for = ignore # ignore/add/remove/force # Add or remove blank line before 'while' nl_before_while = ignore # ignore/add/remove/force # Add or remove blank line after 'while' statement nl_after_while = ignore # ignore/add/remove/force # Add or remove blank line before 'switch' nl_before_switch = ignore # ignore/add/remove/force # Add or remove blank line after 'switch' statement nl_after_switch = ignore # ignore/add/remove/force # Add or remove blank line before 'do' nl_before_do = ignore # ignore/add/remove/force # Add or remove blank line after 'do/while' statement nl_after_do = ignore # ignore/add/remove/force # Whether to double-space commented-entries in struct/enum nl_ds_struct_enum_cmt = false # false/true # Whether to double-space before the close brace of a struct/union/enum # (lower priority than 'eat_blanks_before_close_brace') nl_ds_struct_enum_close_brace = false # false/true # Add or remove a newline around a class colon. # Related to pos_class_colon, nl_class_init_args, and pos_comma. nl_class_colon = ignore # ignore/add/remove/force # Change simple unbraced if statements into a one-liner # 'if(b)\n i++;' => 'if(b) i++;' nl_create_if_one_liner = false # false/true # Change simple unbraced for statements into a one-liner # 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);' nl_create_for_one_liner = false # false/true # Change simple unbraced while statements into a one-liner # 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' nl_create_while_one_liner = false # false/true # # Positioning options # # The position of arithmetic operators in wrapped expressions pos_arith = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of assignment in wrapped expressions. # Do not affect '=' followed by '{' pos_assign = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of boolean operators in wrapped expressions pos_bool = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of comparison operators in wrapped expressions pos_compare = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of conditional (b ? t : f) operators in wrapped expressions pos_conditional = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in wrapped expressions pos_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in the constructor initialization list pos_class_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of colons between constructor and member initialization pos_class_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # # Line Splitting options # # Try to limit code width to N number of columns code_width = 0 # number # Whether to fully split long 'for' statements at semi-colons ls_for_split_full = false # false/true # Whether to fully split long function protos/calls at commas ls_func_split_full = false # false/true # Whether to split lines as close to code_width as possible and ignore some groupings ls_code_width = false # false/true # # Blank line options # # The maximum consecutive newlines nl_max = 0 # number # The number of newlines after a function prototype, if followed by another function prototype nl_after_func_proto = 0 # number # The number of newlines after a function prototype, if not followed by another function prototype nl_after_func_proto_group = 0 # number # The number of newlines after '}' of a multi-line function body nl_after_func_body = 0 # number # The number of newlines after '}' of a multi-line function body in a class declaration nl_after_func_body_class = 0 # number # The number of newlines after '}' of a single line function body nl_after_func_body_one_liner = 0 # number # The minimum number of newlines before a multi-line comment. # Doesn't apply if after a brace open or another multi-line comment. nl_before_block_comment = 0 # number # The minimum number of newlines before a single-line C comment. # Doesn't apply if after a brace open or other single-line C comments. nl_before_c_comment = 0 # number # The minimum number of newlines before a CPP comment. # Doesn't apply if after a brace open or other CPP comments. nl_before_cpp_comment = 0 # number # Whether to force a newline after a multi-line comment. nl_after_multiline_comment = false # false/true # The number of newlines after '}' or ';' of a struct/enum/union definition nl_after_struct = 0 # number # The number of newlines after '}' or ';' of a class definition nl_after_class = 0 # number # The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # Will not change the newline count if after a brace open. # 0 = No change. nl_before_access_spec = 0 # number # The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # 0 = No change. nl_after_access_spec = 0 # number # The number of newlines between a function def and the function comment. # 0 = No change. nl_comment_func_def = 0 # number # The number of newlines after a try-catch-finally block that isn't followed by a brace close. # 0 = No change. nl_after_try_catch_finally = 0 # number # The number of newlines before and after a property, indexer or event decl. # 0 = No change. nl_around_cs_property = 0 # number # The number of newlines between the get/set/add/remove handlers in C#. # 0 = No change. nl_between_get_set = 0 # number # Add or remove newline between C# property and the '{' nl_property_brace = ignore # ignore/add/remove/force # Whether to remove blank lines after '{' eat_blanks_after_open_brace = false # false/true # Whether to remove blank lines before '}' eat_blanks_before_close_brace = false # false/true # How aggressively to remove extra newlines not in preproc. # 0: No change # 1: Remove most newlines not handled by other config # 2: Remove all newlines and reformat completely by config nl_remove_extra_newlines = 0 # number # Whether to put a blank line before 'return' statements, unless after an open brace. nl_before_return = false # false/true # Whether to put a blank line after 'return' statements, unless followed by a close brace. nl_after_return = false # false/true # Whether to put a newline after a Java annotation statement. # Only affects annotations that are after a newline. nl_after_annotation = ignore # ignore/add/remove/force # Controls the newline between two annotations. nl_between_annotation = ignore # ignore/add/remove/force # # Code modifying options (non-whitespace) # # Add or remove braces on single-line 'do' statement mod_full_brace_do = remove # ignore/add/remove/force # Add or remove braces on single-line 'for' statement mod_full_brace_for = remove # ignore/add/remove/force # Add or remove braces on single-line function definitions. (Pawn) mod_full_brace_function = ignore # ignore/add/remove/force # Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. mod_full_brace_if = remove # ignore/add/remove/force # Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. # If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. mod_full_brace_if_chain = false # false/true # Don't remove braces around statements that span N newlines mod_full_brace_nl = 2 # number # Add or remove braces on single-line 'while' statement mod_full_brace_while = remove # ignore/add/remove/force # Add or remove braces on single-line 'using ()' statement mod_full_brace_using = ignore # ignore/add/remove/force # Add or remove unnecessary paren on 'return' statement mod_paren_on_return = remove # ignore/add/remove/force # Whether to change optional semicolons to real semicolons mod_pawn_semicolon = false # false/true # Add parens on 'while' and 'if' statement around bools mod_full_paren_if_bool = true # false/true # Whether to remove superfluous semicolons mod_remove_extra_semicolon = true # false/true # If a function body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_function_closebrace_comment = 0 # number # If a switch body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_switch_closebrace_comment = 0 # number # If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after # the #endif, a comment will be added. mod_add_long_ifdef_endif_comment = 0 # number # If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after # the #else, a comment will be added. mod_add_long_ifdef_else_comment = 0 # number # If TRUE, will sort consecutive single-line 'import' statements [Java, D] mod_sort_import = false # false/true # If TRUE, will sort consecutive single-line 'using' statements [C#] mod_sort_using = false # false/true # If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C] # This is generally a bad idea, as it may break your code. mod_sort_include = false # false/true # If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace. mod_move_case_break = true # false/true # Will add or remove the braces around a fully braced case statement. # Will only remove the braces if there are no variable declarations in the block. mod_case_brace = ignore # ignore/add/remove/force # If TRUE, it will remove a void 'return;' that appears as the last statement in a function. mod_remove_empty_return = true # false/true # # Comment modifications # # Try to wrap comments at cmt_width columns cmt_width = 0 # number # Set the comment reflow mode (default: 0) # 0: no reflowing (apart from the line wrapping due to cmt_width) # 1: no touching at all # 2: full reflow cmt_reflow_mode = 1 # number # If false, disable all multi-line comment changes, including cmt_width. keyword substitution, and leading chars. # Default is true. cmt_indent_multi = true # false/true # Whether to group c-comments that look like they are in a block cmt_c_group = false # false/true # Whether to put an empty '/*' on the first line of the combined c-comment cmt_c_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined c-comment cmt_c_nl_end = false # false/true # Whether to group cpp-comments that look like they are in a block cmt_cpp_group = false # false/true # Whether to put an empty '/*' on the first line of the combined cpp-comment cmt_cpp_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined cpp-comment cmt_cpp_nl_end = false # false/true # Whether to change cpp-comments into c-comments cmt_cpp_to_c = false # false/true # Whether to put a star on subsequent comment lines cmt_star_cont = false # false/true # The number of spaces to insert at the start of subsequent comment lines cmt_sp_before_star_cont = 0 # number # The number of spaces to insert after the star on subsequent comment lines cmt_sp_after_star_cont = 0 # number # For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of # the comment are the same length. Default=True cmt_multi_check_last = true # false/true # The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment. # Will substitute $(filename) with the current file's name. cmt_insert_file_header = "" # string # The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment. # Will substitute $(filename) with the current file's name. cmt_insert_file_footer = "" # string # The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. # Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. # Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } cmt_insert_func_header = "" # string # The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. # Will substitute $(class) with the class name. cmt_insert_class_header = "" # string # The filename that contains text to insert before a Obj-C message specification if the method isn't preceeded with a C/C++ comment. # Will substitute $(message) with the function name and $(javaparam) with the javadoc @param and @return stuff. cmt_insert_oc_msg_header = "" # string # If a preprocessor is encountered when stepping backwards from a function name, then # this option decides whether the comment should be inserted. # Affects cmt_insert_oc_msg_header, cmt_insert_func_header and cmt_insert_class_header. cmt_insert_before_preproc = false # false/true # # Preprocessor options # # Control indent of preprocessors inside #if blocks at brace level 0 pp_indent = remove # ignore/add/remove/force # Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false) pp_indent_at_level = false # false/true # If pp_indent_at_level=false, specifies the number of columns to indent per level. Default=1. pp_indent_count = 1 # number # Add or remove space after # based on pp_level of #if blocks pp_space = ignore # ignore/add/remove/force # Sets the number of spaces added with pp_space pp_space_count = 0 # number # The indent for #region and #endregion in C# and '#pragma region' in C/C++ pp_indent_region = 0 # number # Whether to indent the code between #region and #endregion pp_region_indent_code = false # false/true # If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level pp_indent_if = 0 # number # Control whether to indent the code between #if, #else and #endif when not at file-level pp_if_indent_code = false # false/true # Whether to indent '#define' at the brace level (true) or from column 1 (false) pp_define_at_level = false # false/true # You can force a token to be a type with the 'type' option. # Example: # type myfoo1 myfoo2 # # You can create custom macro-based indentation using macro-open, # macro-else and macro-close. # Example: # macro-open BEGIN_TEMPLATE_MESSAGE_MAP # macro-open BEGIN_MESSAGE_MAP # macro-close END_MESSAGE_MAP # # You can assign any keyword to any type with the set option. # set func_call_user _ N_ # # The full syntax description of all custom definition config entries # is shown below: # # define custom tokens as: # - embed whitespace in token using '' escape character, or # put token in quotes # - these: ' " and ` are recognized as quote delimiters # # type token1 token2 token3 ... # ^ optionally specify multiple tokens on a single line # define def_token output_token # ^ output_token is optional, then NULL is assumed # macro-open token # macro-close token # macro-else token # set id token1 token2 ... # ^ optionally specify multiple tokens on a single line # ^ id is one of the names in token_enum.h sans the CT_ prefix, # e.g. PP_PRAGMA # # all tokens are separated by any mix of ',' commas, '=' equal signs # and whitespace (space, tab) # xoreos-tools-0.0.5/AUTHORS000066400000000000000000000103601331663051500152440ustar00rootroot00000000000000xoreos-tools - Tools to help with xoreos development Copyright (c) 2012-2018 by the following: Sven Hesse (DrMcCoy) Matthew Hoops (clone2727) Contributors: Beren Minor cc9cii Enrico Horn (Farmboy0) kevL Anthony J. Bentley Ben Rosser (TC01) Michael Drüing (darkstar) Matthias Gatto (cosmo-ray) Alexander Nahapetyan (NAAleks) Patrick (Nostritius) xoreos-tools is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. xoreos-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with xoreos-tools. If not, see . The Infinity engine, Aurora engine, Odyssey engine and Eclipse engine are registered trademarks of BioWare Corp., a subsidiary of Electronic Arts, Inc. The Electron engine and Lycium engine are trademarks of BioWare Corp., a subsidiary of Electronic Arts, Inc. Bink is a registered trademark of RAD Game Tools, Inc. Neverwinter Nights is a registered trademark of Wizards of the Coast, a subsidiary of Hasbro Inc. Star Wars, Knights of the Old Republic and The Sith Lords are registered trademarks of Lucasfilm Entertainment Company Ltd., a subsidiary of The Walt Disney Company. Jade Empire is a registered trademark of BioWare Corp., a subsidiary of Electronic Arts, Inc. Sonic the Hedgehog is a registered trademark of Sega Corporation. The Witcher is a registered trademark of CD Projekt S.A. Dragon Age is a registered trademark of Electronic Arts, Inc. All rights reserved. boost.m4 ******** xoreos-tools uses Benoit Sigoure's boost.m4 autoconf macros () to check for the needed Boost libraries. boost.m4 is licensed under version 3 or later of the GNU General Public License. For the full license text, see COPYING or . UTF-8 CPP ********* xoreos-tools uses the lightweight header-only UTF-8 CPP library () for handling UTF-8 encoded strings. UTF-8 CPP is licensed under the Boost Software License. See utf8cpp/utf8.h or for details. ScummVM code ************ xoreos-tools uses some ScummVM () code, most prominently the endian, singleton and stream code. ScummVM is licensed under version 2 or later of the GNU General Public License. For the full license text, see doc/LICENSE.GPLv2 or . Nintendo DS formats ******************* xoreos-tools includes readers for various Nintendo DS file formats, based on code in Tinke by pleoNeX (), licensed under version 3 or later of the GNU General Public License. For the full license text, see COPYING or . They are also based on lowlines' file format specifications () and the Nintendo DS information documentation GBATEK by Martin Korth (). Google Test *********** xoreos-tools uses Google Test (), Google's C++ test framework. Google Test is licensed under the terms of the 3-clause BSD license. For the full license text, see tests/googletest/LICENSE or . Libraries ********* In addition to the above, xoreos-tools is also only possible because of the people working for the following libraries and organizations. Many thanks! - libiconv - zlib - libxml2 - Boost xoreos-tools-0.0.5/BUILDDEP.md000066400000000000000000000005551331663051500157130ustar00rootroot00000000000000Build-time library dependencies =============================== - iconv - zlib (>= 1.2.3) - libxml2 (>= 2.8.0) - Boost (>= 1.53.0) - Boost.Utility - Boost.StringAlgo - Boost.System - Boost.Filesystem - Boost.Regex - Boost.Hash - Boost.Function - Boost.Bind - Boost.Uuid - Boost.Smart_Ptr - Boost.ScopeExit - Boost.Atomic - Boost.Locale xoreos-tools-0.0.5/CMakeLists.txt000066400000000000000000000363661331663051500167520ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . cmake_minimum_required(VERSION 2.8.12) project(xoreos-tools CXX) set(xoreos-tools_VERSION 0.0.5) # ------------------------------------------------------------------------- # options! option(Boost_USE_STATIC_LIBS "Use Boost static libraries" OFF) # ------------------------------------------------------------------------- # load some cmake modules from cmake/ subfolder list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) include(GNUInstallDirs) include(CheckIncludeFileCXX) include(CMakeAM) include(SetCheckCompilerFlag) # ------------------------------------------------------------------------- # platform specific flags if(CMAKE_HOST_APPLE) add_definitions(-DUNIX -DMACOSX) elseif(CMAKE_HOST_UNIX) add_definitions(-DUNIX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -fno-show-column") # Wrap libraries in --start-group and --end-group to easily support static linking and symbol resolution, maybe useful on APPLE also, but I don't know string(REPLACE "" "-Wl,--gc-sections -Wl,--start-group -Wl,--end-group" CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE}") string(REPLACE "" "-Wl,--start-group -Wl,--end-group" CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}") string(REPLACE "" "-Wl,--start-group -Wl,--end-group" CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE}") elseif(CMAKE_HOST_WIN32) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:libcmt.lib") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") endif() else() message(STATUS "Unknown platform, maybe not supported") endif() # C++ standard we're compiling against # set_check_compiler_flag_cxx("-std=c++03") # Compiler warning flags, not for MSVC if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # Extra warnings valid for both C and C++ set_check_compiler_flag_cxx("-Wall") set_check_compiler_flag_cxx("-Wignored-qualifiers") set_check_compiler_flag_cxx("-Wpointer-arith") set_check_compiler_flag_cxx("-Wshadow") set_check_compiler_flag_cxx("-Wsign-compare") set_check_compiler_flag_cxx("-Wtype-limits") set_check_compiler_flag_cxx("-Wuninitialized") set_check_compiler_flag_cxx("-Wunused-parameter") set_check_compiler_flag_cxx("-Wunused-but-set-parameter") set_check_compiler_flag_cxx("-Wduplicated-cond") set_check_compiler_flag_cxx("-Wduplicated-branches") set_check_compiler_flag_cxx("-Wlogical-op") set_check_compiler_flag_cxx("-Wshift-negative-value") set_check_compiler_flag_cxx("-Wshift-overflow=2") set_check_compiler_flag_cxx("-Wimplicit-fallthrough") set_check_compiler_flag_cxx("-Wvla") # Extra warnings valid for C++ set_check_compiler_flag_cxx("-Wnon-virtual-dtor") # Disable warnings about hiding virtual functions from a base class. We don't care set_check_compiler_flag_cxx("-Woverloaded-virtual" "-Wno-overloaded-virtual") # Disable warnings about the long long type. We need it set_check_compiler_flag_cxx("-Wlong-long" "-Wno-long-long") set_check_compiler_flag_cxx("-Wc++11-long-long" "-Wno-c++11-long-long") # clang is far too trigger-happy on this warning, so let's disable it set_check_compiler_flag_cxx("-Wundefined-var-template" "-Wno-undefined-var-template") endif() # platform specific warning settings if(CMAKE_HOST_WIN32) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") string(REGEX REPLACE "/W[0-4]" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") endif() set(WARNINGS_DISABLE # ignore 4250 # 'class1' : inherits 'class2::member' via dominance #4101 # 'identifier' : unreferenced local variable 4100 # 'identifier' : unreferenced formal parameter 4127 # conditional expression is constant (template parameter already evaluated) 4189 # 'identifier' : local variable is initialized but not referenced 4245 # 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch 4435 # 'class1' : Object layout under /vd2 will change due to virtual base 'class2' 4510 # 'class' : default constructor could not be generated 4512 # 'class' : assignment operator could not be generated 4610 # object 'class' can never be instantiated - user-defined constructor required #4702 # unreachable code 4706 # assignment within conditional expression 4710 # 'function' : function not inlined 4714 # function 'function' marked as __forceinline not inlined # investigate later 4305 # 'identifier' : truncation from 'type1' to 'type2' 4244 # 'argument' : conversion from 'type1' to 'type2', possible loss of data 4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data 4996 # 'function': was declared deprecated # investigate now #4005 # 'identifier' : macro redefinition #4800 # 'type' : forcing value to bool 'true' or 'false' (performance warning) #4146 # unary minus operator applied to unsigned type, result still unsigned ) foreach(d ${WARNINGS_DISABLE}) set(WARNINGS "${WARNINGS} /wd${d}") endforeach(d) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNINGS} ${MT_BUILD}") endif() endif() # header detection, could get rid of it, but it is used by lua as well include(CheckIncludeFileCXX) function(check_has_header FILE_NAME PP_NAME) check_include_file_cxx(${FILE_NAME} ${PP_NAME}) if(${PP_NAME}) add_definitions(-D${PP_NAME}=1) endif() endfunction() check_has_header("stdint.h" HAVE_STDINT_H) check_has_header("inttypes.h" HAVE_INTTYPES_H) check_has_header("sys/types.h" HAVE_SYS_TYPES_H) # type size checks include(CheckTypeSize) check_type_size("char" SIZEOF_CHAR LANGUAGE CXX) check_type_size("short" SIZEOF_SHORT LANGUAGE CXX) check_type_size("int" SIZEOF_INT LANGUAGE CXX) check_type_size("long" SIZEOF_LONG LANGUAGE CXX) check_type_size("long long" SIZEOF_LONG_LONG LANGUAGE CXX) check_type_size("void *" SIZEOF_VOID_P LANGUAGE CXX) check_type_size("intptr_t" SIZEOF_INTPTR_T LANGUAGE CXX) check_type_size("uintptr_t" SIZEOF_UINTPTR_T LANGUAGE CXX) if(HAVE_SIZEOF_CHAR AND SIZEOF_CHAR) add_definitions(-DSIZEOF_CHAR=${SIZEOF_CHAR}) endif() if(HAVE_SIZEOF_SHORT AND SIZEOF_SHORT) add_definitions(-DSIZEOF_SHORT=${SIZEOF_SHORT}) endif() if(HAVE_SIZEOF_INT AND SIZEOF_INT) add_definitions(-DSIZEOF_INT=${SIZEOF_INT}) endif() if(HAVE_SIZEOF_LONG AND SIZEOF_LONG) add_definitions(-DSIZEOF_LONG=${SIZEOF_LONG}) endif() if(HAVE_SIZEOF_LONG_LONG AND SIZEOF_LONG_LONG) add_definitions(-DSIZEOF_LONG_LONG=${SIZEOF_LONG_LONG}) endif() if(HAVE_SIZEOF_VOID_P AND SIZEOF_VOID_P) add_definitions(-DSIZEOF_VOID_P=${SIZEOF_VOID_P}) endif() if(HAVE_SIZEOF_INTPTR_T AND SIZEOF_INTPTR_T) add_definitions(-DHAVE_INTPTR_T=1) endif() if(HAVE_SIZEOF_UINTPTR_T AND SIZEOF_UINTPTR_T) add_definitions(-DHAVE_UINTPTR_T=1) endif() # function detection include(CheckCXXSymbolExists) function(check_has_function FUNCTION_NAME FILE_NAME PP_NAME) check_cxx_symbol_exists(${FUNCTION_NAME} "${FILE_NAME}" ${PP_NAME}) if(${PP_NAME}) add_definitions(-D${PP_NAME}=1) endif() endfunction() check_has_function(strtof "cstdlib" HAVE_STRTOF) check_has_function(strtoll "cstdlib" HAVE_STRTOLL) check_has_function(strtoull "cstdlib" HAVE_STRTOULL) # endianess detection, could be replaced by including Boost.Config include(TestBigEndian) # CMake's endian check needs C and won't work with just CXX... enable_language(C) test_big_endian(XOREOS_BIG_ENDIAN) if(XOREOS_BIG_ENDIAN) add_definitions(-DXOREOS_BIG_ENDIAN=1) else() add_definitions(-DXOREOS_LITTLE_ENDIAN=1) endif() # pthreads, for our unit tests if(NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "MinGW") find_package(Threads) endif() set(HAVE_PTHREAD ${CMAKE_USE_PTHREADS_INIT}) if(CMAKE_USE_PTHREADS_INIT) set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT}) endif() # ------------------------------------------------------------------------- # subfolders where built binaries and libraries will be located, relative to the build folder set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) # ------------------------------------------------------------------------- # find the required libraries set(XOREOSTOOLS_LIBRARIES "") find_package(ZLIB REQUIRED) include_directories(${ZLIB_INCLUDE_DIRS}) list(APPEND XOREOSTOOLS_LIBRARIES ${ZLIB_LIBRARIES}) find_package(Boost COMPONENTS system filesystem regex atomic locale REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) list(APPEND XOREOSTOOLS_LIBRARIES ${Boost_LIBRARIES}) find_package(LibXml2 REQUIRED) include_directories(${LIBXML2_INCLUDE_DIR}) list(APPEND XOREOSTOOLS_LIBRARIES ${LIBXML2_LIBRARIES}) find_package(Iconv REQUIRED) include_directories(${ICONV_INCLUDE_DIRS}) list(APPEND XOREOSTOOLS_LIBRARIES ${ICONV_LIBRARIES}) if(ICONV_SECOND_ARGUMENT_IS_CONST) add_definitions(-DICONV_CONST=const) else(ICONV_SECOND_ARGUMENT_IS_CONST) add_definitions(-DICONV_CONST=) endif(ICONV_SECOND_ARGUMENT_IS_CONST) # ------------------------------------------------------------------------- # custom unit testing target, because CMake's make test is pretty useless add_custom_target(check ${CMAKE_COMMAND} -E echo CWD=${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E echo CMD=${CMAKE_CTEST_COMMAND} -C $ COMMAND ${CMAKE_COMMAND} -E echo ---------------------------------- COMMAND ${CMAKE_COMMAND} -E env CTEST_OUTPUT_ON_FAILURE=1 ${CMAKE_CTEST_COMMAND} -C $ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) # ------------------------------------------------------------------------- # xoreos-tools main targets, parsed from the Automake rules.mk files include_directories(${PROJECT_SOURCE_DIR}) add_definitions(-DPACKAGE_STRING="xoreos-tools ${xoreos-tools_VERSION}") parse_automake(src/rules.mk) # unit tests depend on the xoreos-tools proper foreach(AM_TARGET ${AM_TARGETS}) add_dependencies(check ${AM_TARGET}) endforeach() foreach(AM_PROGRAM ${AM_PROGRAMS}) target_link_libraries(${AM_PROGRAM} ${XOREOSTOOLS_LIBRARIES}) endforeach() # install programs to bin dir install( TARGETS ${AM_PROGRAMS} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) # ------------------------------------------------------------------------- # xoreos-tools man pages and docs parse_automake(man/rules.mk) # install man pages install( FILES ${AM_MAN1_MANS} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 ) install( FILES ${AM_MAN6_MANS} DESTINATION ${CMAKE_INSTALL_MANDIR}/man6 ) parse_automake(doc/rules.mk) # install docs install( FILES ${AM_DOCS} DESTINATION ${CMAKE_INSTALL_DOCDIR} ) # ------------------------------------------------------------------------- # unit tests, parsed from the Automake rules.mk files enable_testing() parse_automake(tests/rules.mk) # they should be build on make check, but not make all foreach(AM_TARGET ${AM_TARGETS}) set_target_properties(${AM_TARGET} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE EXCLUDE_FROM_ALL TRUE) add_dependencies(check ${AM_TARGET}) # ctest counts skipped tests as failed... -.- get_target_property(TARGET_SOURCES ${AM_TARGET} SOURCES) foreach(TARGET_SOURCE ${TARGET_SOURCES}) set_source_files_properties(${TARGET_SOURCE} PROPERTIES APPEND PROPERTY COMPILE_DEFINITIONS "SKIP_RETURN_CODE=0") endforeach() endforeach() foreach(AM_PROGRAM ${AM_PROGRAMS}) target_link_libraries(${AM_PROGRAM} ${XOREOSTOOLS_LIBRARIES}) add_test(NAME ${AM_PROGRAM} COMMAND ${AM_PROGRAM}) endforeach() # ------------------------------------------------------------------------- # uninstall target # Code taken from https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake if(NOT TARGET uninstall) configure_file("${CMAKE_SOURCE_DIR}/cmake/CMakeUninstall.cmake" "${CMAKE_BINARY_DIR}/CMakeUninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/CMakeUninstall.cmake) endif() # ------------------------------------------------------------------------- # try to add version information from git to src/version/version.cpp # this is not 100% clean, and doesn't reconfigure when there's only a local change since last # build (so it does not always add the .dirty suffix) # get build timestamp, but heed SOURCE_DATE_EPOCH set(DATE_FMT "%Y-%m-%dT%H:%M:%SZ") if(DEFINED ENV{SOURCE_DATE_EPOCH}) execute_process(COMMAND "date" "-u" "-d" "@$ENV{SOURCE_DATE_EPOCH}" "+${DATE_FMT}" OUTPUT_VARIABLE XOREOS_BUILDDATE OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE DATE_RETCODE ERROR_QUIET) if(NOT "${DATE_RETCODE}" STREQUAL "0") execute_process(COMMAND "date" "-u" "-r" "$ENV{SOURCE_DATE_EPOCH}" "+${DATE_FMT}" OUTPUT_VARIABLE XOREOS_BUILDDATE OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE DATE_RETCODE ERROR_QUIET) if(NOT "${DATE_RETCODE}" STREQUAL "0") string(TIMESTAMP XOREOS_BUILDDATE "${DATE_FMT}" UTC) endif() endif() else() string(TIMESTAMP XOREOS_BUILDDATE "${DATE_FMT}" UTC) endif() set_property(SOURCE src/version/version.cpp APPEND PROPERTY COMPILE_DEFINITIONS XOREOS_BUILDDATE="${XOREOS_BUILDDATE}") find_package(Git) if(GIT_FOUND) execute_process(COMMAND ${GIT_EXECUTABLE} describe --long --match desc/* OUTPUT_VARIABLE XOREOS_REVDESC OUTPUT_STRIP_TRAILING_WHITESPACE) string(REGEX REPLACE "desc/(.*)-([^-]*)-([^-]*)" "\\1+\\2.\\3" XOREOS_REVDESC "${XOREOS_REVDESC}") execute_process( COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR} update-index --refresh --unmerged COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR} diff-index --quiet HEAD OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE XOREOS_REVDIRT ) if(NOT XOREOS_REVDIRT EQUAL 0) set(XOREOS_REVDESC "${XOREOS_REVDESC}.dirty") endif() string(REGEX REPLACE "^[^+]*\\+" "" XOREOS_REV "${XOREOS_REVDESC}") message(STATUS "Building version: ${XOREOS_REVDESC}") set_property(SOURCE src/version/version.cpp APPEND PROPERTY COMPILE_DEFINITIONS XOREOS_REVDESC="${XOREOS_REVDESC}") set_property(SOURCE src/version/version.cpp APPEND PROPERTY COMPILE_DEFINITIONS XOREOS_REV="${XOREOS_REV}") # use .git/logs/HEAD to track if git state has changed and if we need to reconfigure if(EXISTS ${CMAKE_SOURCE_DIR}/.git/logs/HEAD) configure_file(${CMAKE_SOURCE_DIR}/.git/logs/HEAD .dirstamp) endif() endif() xoreos-tools-0.0.5/CODE_OF_CONDUCT.md000066400000000000000000000062321331663051500167760ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainer Sven Hesse at sven.hesse@drmccoy.de. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Confidentiality with regard to the reporter of an incident will be maintained. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ xoreos-tools-0.0.5/CONTRIBUTING.md000066400000000000000000000014721331663051500164310ustar00rootroot00000000000000We welcome and value contributions, but please have a look at the [Developer's Central page in our wiki](https://wiki.xoreos.org/index.php?title=Developer_Central) before contributing to ensure you are aware of our commit guidelines and coding style, and read our [Code of Conduct](CODE_OF_CONDUCT.md). Pull requests and patches will be finely checked for proper adherence to our guidelines and we will expect you to fix any and all deviations before the changes are merged into the official repository. This is by no means meant personally or an indication of reluctance with accepting your changes. If you wish to make further long-term contributions to xoreos, we will gladly accept you as a team member and give you direct push access to the repository after we have made sure you can follow our guidelines on your own. xoreos-tools-0.0.5/COPYING000066400000000000000000001045151331663051500152350ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . xoreos-tools-0.0.5/ChangeLog000066400000000000000000000102511331663051500157450ustar00rootroot00000000000000Tuesday, 2018-07-03 (Version 0.0.5) - Tools added: - ssf2xml - xml2ssf - erf - DOCS: - Corrected example section of the convert2da manpage - Improved documentation in various files - BUILD: - Simplified compilation to only use a C++ compiler - Added more optional compilation warning flags - Pulled in Boost, to ease sync with xoreos - Changed our autotools setup to be non-recursive - Added support for SOURCE_DATE_EPOCH when building, which is necessary for reproducible builds - Dropped telling the compiler to build in C++03 mode, many Linux distros build libraries with C++11 features now - COMMON: - Added missing kEncodingCP1251 handling in several functions - Moved DEFLATE decompression into its own files - Corrected the StreamTokenizer behaviour in a corner case - Added checks for nullptr in stream and encoding methods - Fixed composeString() for the INT*_MIN cases - Rewrote and unified the command line parsing - AURORA: - Unified some code between xoreos and xoreos-tools - Fixed a potential field overflow in the binary 2DA writer - Fixed reading of NSBTX with truncated palette - Fixed reading of 2DA with indented rows - Added exceptions for as of yet unknown GFF4 configurations - IMAGES: - Loosened restrictions on images, allowing NPOT images - Implemented loading of Jade Empire lightmap textures - GFF2XML: - Added an --encoding parameter to overwrite the encoding used in GFF3 LocStrings - Removed empty label property on structs with no label - Removed alias on generic lists; their labels are indices - TLK2XML: - Fixed corner case of entries with a sound, but no text - DIST: - Added Fedora package build files - MISC: - Improved code consistency in some places - Marked several classes correctly as noncopyable - Introduced various smart pointer templates into the codebase, making it cleaner and more leak-free - Added support for and implemented unit tests for many classes in the Common and Aurora namespaces Monday, 2016-02-01 (Version 0.0.4) - Tools added: - fixpremiumgff - ncsdis - GFF2XML: - Improved parameter parsing to not silently ignore extra filenames - Added a status message when converting directly into a file - Added support for GFF3s in Neverwinter Nights premium modules - TLK2XML: - Improved parameter parsing to not silently ignore extra filenames - Added a status message when converting directly into a file - UNERF: - Added support for Neverwinter Nights premium modules - BUILD: - Fixed small bug preventing the CMake build system to be used with non-MSVC compilers - Added dynamic supported warning flag detection to CMake - DOCS: - Improved documentation in various files - Rewrote manpages to use semantic -mdoc macros - MISC: - Changed C-style casts to static_cast and reinterpret_cast in various places - Improved const-correctness in various places - Ran many file format loaders through afl and fixed all crashes Wednesday, 2015-09-30 (Version 0.0.3) - Tools added: - xml2tlk - BUILD: - Fixed CMake compilation on Windows with MSVC - Fixed configure with zlib 1.2.3.4 - 1.2.3.9 - GFF2XML: - Fixed various XML formatting issues - Changed GFF detection to accept currently-unknown types - XOREOSTEX2TGA: - Added support for TPC cube maps - CONVERT2DA: - Added support for writing binary 2DA files - TLK2XML: - Added flags to implicitly specify encoding by game Monday, 2015-07-27 (Version 0.0.2) - Made all tools display version information with --version - Fixed Windows UTF-8 compatibility - Renamed texture2tga to xoreostex2tga, for disambiguation - Added a man page for each tool - Added build files for Arch and Debian packages Tuesday, 2015-07-14 (Version 0.0.1) - Tools added: - gff2xml - tlk2xml - convert2da - unerf - unherf - unrim - unnds - unnsbtx - unkeybif - desmall - texture2tga - nbfs2tga - ncgr2tga - cbgt2tga - cdpth2tga - Bump version number to be in sync with xoreos Monday, 2014-10-20 (Version 0.0.0) - Created a dedicated repository for the tools Sunday, 2012-07-22 (Version 0.0.0-pre) - Initial empty frame - Added the ancient, obsolete libeos - Added file format specs xoreos-tools-0.0.5/Makefile.am000066400000000000000000000052451331663051500162360ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . # The main "controller" automake recipe. We're setting up all our # global build variables here, then recursively include all other # build recipe, creating a flat non-recursive automake setup. # Use the m4 directory for extra m4 autoconf scripts. ACLOCAL_AMFLAGS = -I m4 --install # Build objects in the same directory as their source files. AUTOMAKE_OPTIONS = subdir-objects # Empty element to make the source lists easier editable. EMPTY = # Initialize the global lists. noinst_HEADERS = noinst_LTLIBRARIES = bin_PROGRAMS = check_LTLIBRARIES = check_PROGRAMS = TESTS = CLEANFILES = EXTRA_DIST = dist_doc_DATA = dist_man1_MANS = # Library compile flags LIBSF_XOREOS = $(XOREOSTOOLS_CFLAGS) LIBSF_GENERAL = $(ZLIB_CFLAGS) $(XML2_CFLAGS) LIBSF_BOOST = $(BOOST_CPPFLAGS) LIBSF = $(LIBSF_XOREOS) $(LIBSF_GENERAL) $(LIBSF_BOOST) # Library linking flags LIBSL_XOREOS = $(XOREOSTOOLS_LIBS) LIBSL_GENERAL = $(LTLIBICONV) $(ZLIB_LIBS) $(XML2_LIBS) LIBSL_BOOST = $(BOOST_SYSTEM_LDFLAGS) $(BOOST_SYSTEM_LIBS) \ $(BOOST_FILESYSTEM_LDFLAGS) $(BOOST_FILESYSTEM_LIBS) \ $(BOOST_REGEX_LDFLAGS) $(BOOST_REGEX_LIBS) \ $(BOOST_ATOMIC_LDFLAGS) $(BOOST_ATOMIC_LIBS) \ $(BOOST_LOCALE_LDFLAGS) $(BOOST_LOCALE_LIBS) LIBSL = $(LIBSL_XOREOS) $(LIBSL_GENERAL) $(LIBSL_BOOST) # Other compiler flags FLAGS_DIR = -I$(srcdir) FLAGS_DEBUG = $(GGDB) FLAGS_STD = $(STD) FLAGS_OPT = $(LTO) $(NATIVE) FLAGS_WARN = $(WARN) $(WERROR) FLAGS = $(FLAGS_DIR) $(FLAGS_DEBUG) $(FLAGS_STD) \ $(FLAGS_OPT) $(FLAGS_WARN) # Putting it all together... AM_CXXFLAGS = $(FLAGS) $(LIBSF) AM_LDFLAGS = $(FLAGS_OPT) LDADD = $(LIBSL) LIBS = # Now include the top-level recipe file and through it, all the # other build recipes. include rules.mk xoreos-tools-0.0.5/NEWS.md000066400000000000000000000061061331663051500152750ustar00rootroot00000000000000Changes in xoreos-tools version 0.0.5 ===================================== This release of the xoreos-tool package features three new tools: ssf2xml, xml2ssf and erf. The first toool, ssf2xml, takes a sound set file as used in the two Neverwinter Nights and the two Knights of the Old Republic games and converts it into a user-readable XML file. That file can then be edited and, with the help of the second new tool, xml2ssf, converted back into a game-readable SSF file. The third new tool is a packer for the ERF archive format. It is the counterpart of the already existing unerf tool, which extracts ERF archives. However, unlike the unerf tool, the erf tool can only create ERF archives of the version 1.0, as used by Neverwinter Nights, Knights of the Old Republic I and II, Jade Empire and The Witcher. Later versions of the format are not yet supported. Apart from that, this release of course also includes a ton of user-invisible code quality and documentation fixes. Changes in xoreos-tools version 0.0.4 ===================================== This release of the xoreos-tools package features two new tools: fixpremiumgff and ncsdis. The first tool, fixpremiumgff, can restore the deliberately broken GFF files found in the BioWare premium modules for Neverwinter Nights. The resulting GFF files can then be edited as normal. The second tool, ncsdis, is a disassembler for the stack-based bytecode of BioWare's NWScript scripting language. It supports the scripts of all games targeted by xoreos and can disassemble them into a full assembly listing. It can also produce a control flow graph in the DOT description language, which can then be plotted into an image by using the dot tools from the GraphViz suite (). Moreover, this release includes a lot of user-invisible code documentation and quality fixes. Changes in xoreos-tools version 0.0.3 ===================================== This release of the xoreos-tools package features a new xml2tlk tool that can convert XML files created by the tlk2xml tool back into a talk table TLK file. Please note that, at the moment, only non-GFF'd TLK files can be written, as used by the two Neverwinter Nights games, the two Knights of the Old Republic games, Jade Empire and The Witcher. TLK files as used by Sonic Chronicles: The Dark Brotherhood and the two Dragon Age games can not be written (they can, however, be read with the tlk2xml tool). Additionally, the convert2da tool gained the ability to write binary 2DA files, as used by the two Knights of the Old Republic games; and xoreostex2tga can now correctly read TPC cube maps. Changes in xoreos-tools version 0.0.2 ===================================== This is the first official release of xoreos-tools, together with xoreos. Included are: - Tools for handling resource archives - unkeybif - unerf - unrim - unherf - unnds - desmall - Tools converting basic resource formats into human-readable form - gff2xml - tlk2xml - convert2da - Tools converting graphics formats into TGA - xoreostex2tga - unnsbtx - nbfs2tga - ncgr2tga - cbgt2tga - cdpth2tga xoreos-tools-0.0.5/README.md000066400000000000000000000123141331663051500154540ustar00rootroot00000000000000xoreos-tools README =================== A collection of tools to help with the reverse-engineering of BioWare's Aurora engine games. xoreos-tools is part of the xoreos project; please see the [xoreos website](https://xoreos.org/) and its [GitHub repositories](https://github.com/xoreos) for details, especially [the main README.md](https://github.com/xoreos/xoreos/blob/master/README.md). The tools included here are licensed under the terms of the [GNU General Public License version 3](https://www.gnu.org/licenses/agpl-3.0.html) or (at your option) any later version. Currently, the following tools are included: * gff2xml: Convert BioWare GFF to XML * tlk2xml: Convert BioWare TLK to XML * ssf2xml: Convert BioWare SSF to XML * xml2tlk: Convert XML back to BioWare TLK * xml2ssf: Convert XML back to BioWare SSF * convert2da: Convert BioWare 2DA/GDA to 2DA/CSV * fixpremiumgff: Repair BioWare GFF files in NWN premium module HAKs * unerf: Extract BioWare ERF archives * unherf: Extract BioWare HERF archives * unrim: Extract BioWare RIM archives * unnds: Extract Nintendo DS roms * unnsbtx: Extract Nintendo NSBTX textures into TGA images * unkeybif: Extract BioWare KEY/BIF archives * erf: Create BioWare ERF archives * desmall: Decompress "small" (Nintendo DS LZSS, types 0x00 and 0x10) files * xoreostex2tga: Convert BioWare's texture formats into TGA * nbfs2tga: Convert Nintendo's raw NBFS images into TGA * ncgr2tga: Convert Nintendo's NCGR images into TGA * cbgt2tga: Convert CBGT images into TGA * cdpth2tga: Convert CDPTH depth images into TGA * ncsdis: Disassemble NWScript bytecode TLK language IDs and encodings ------------------------------ Aurora games use numerical language IDs to identify which language a TLK file holds. Unfortunately, those language IDs vary between games, and so does the encoding used for strings in those TLK files. There is no way to autodetect this information, so it has to be provided to tools handling those files, in one way or another. For the tools tlk2xml and xml2tlk, you can specify this encoding either directly, or by giving the game the TLK is from. Please note that this does not work for Sonic Chronicles: The Dark Brotherhood, because its TLK files do not provide a language ID. Neverwinter Nights, Neverwinter Nights 2, Knights of the Old Republic, Knights of the Old Republic 2, Jade Empire: | Language ID | Language | Encoding | |------------:|:----------------------|:---------| | 0 | English | CP-1252 | | 1 | French | CP-1252 | | 2 | German | CP-1252 | | 3 | Italian | CP-1252 | | 4 | Spanish | CP-1252 | | 5 | Polish | CP-1250 | | 128 | Korean | CP-949 | | 129 | Chinese (Traditional) | CP-950 | | 130 | Chinese (Simplified) | CP-936 | | 131 | Japanese | CP-932 | The Witcher: | Language ID | Language | Encoding | |------------:|:----------------------|:---------| | 0 | "Debug" | UTF-8 | | 3 | English | UTF-8 | | 5 | Polish | UTF-8 | | 10 | German | UTF-8 | | 11 | French | UTF-8 | | 12 | Spanish | UTF-8 | | 13 | Italian | UTF-8 | | 14 | Russian | UTF-8 | | 15 | Czech | UTF-8 | | 16 | Hungarian | UTF-8 | | 20 | Korean | UTF-8 | | 21 | Chinese (Traditional) | UTF-8 | | 22 | Chinese (Simplified) | UTF-8 | Sonic Chronicles: The Dark Brotherhood: | Language ID | Language | Encoding | |------------:|:----------------------|:---------| | - | English | CP-1252 | | - | French | CP-1252 | | - | German | CP-1252 | | - | Italian | CP-1252 | | - | Spanish | CP-1252 | | - | Japanese | UTF-8 | Dragon Age: Origins, Dragon Age II: | Language ID | Language | Encoding | |------------:|:----------------------|:---------| | 0 | English | UTF-16LE | | 1 | French | UTF-16LE | | 2 | Russian | UTF-16LE | | 3 | Italian | UTF-16LE | | 4 | German | UTF-16LE | | 5 | Polish | UTF-16LE | | 6 | Spanish | UTF-16LE | | 7 | Czech | UTF-16LE | | 8 | Hungarian | UTF-16LE | | 9 | Korean | UTF-16LE | | 10 | Japanese | UTF-16LE | Status [![Build Status](https://travis-ci.org/xoreos/xoreos-tools.svg?branch=master)](https://travis-ci.org/xoreos/xoreos-tools) [![Coverity Status](https://scan.coverity.com/projects/3296/badge.svg)](https://scan.coverity.com/projects/3296) ------ Contact ------- To contact us, please either write to [mailing list](https://xoreos.org/mailman/listinfo/xoreos-devel), or join our IRC channel #xoreos on Freenode. xoreos-tools-0.0.5/TODO000066400000000000000000000000631331663051500146630ustar00rootroot00000000000000See xoreos-tools-0.0.5/autogen.sh000077500000000000000000000021651331663051500162010ustar00rootroot00000000000000#!/bin/sh # xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . test -n "$srcdir" || srcdir=`dirname "$0"` test -n "$srcdir" || srcdir=. olddir=`pwd` cd $srcdir AUTORECONF=`which autoreconf` if test -z $AUTORECONF; then echo "*** No autoreconf found, please install it ***" exit 1 fi autoreconf --force --install --verbose cd $olddir xoreos-tools-0.0.5/build-aux/000077500000000000000000000000001331663051500160665ustar00rootroot00000000000000xoreos-tools-0.0.5/build-aux/config.rpath000066400000000000000000000000001331663051500203610ustar00rootroot00000000000000xoreos-tools-0.0.5/cmake/000077500000000000000000000000001331663051500152545ustar00rootroot00000000000000xoreos-tools-0.0.5/cmake/CMakeAM.cmake000066400000000000000000000245501331663051500174620ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . function(am_read_lines FILE_NAME OUTPUT_VARIABLE) message(STATUS "Parsing ${FILE_NAME}...") file(READ ${FILE_NAME} FILE_CONTENTS) string(REGEX REPLACE "\\$\\(([^ )]+)\\)" "\${\\1}" FILE_CONTENTS "${FILE_CONTENTS}") string(REGEX REPLACE "\\$\\(shell [^)]+\\)" "" FILE_CONTENTS "${FILE_CONTENTS}") string(REGEX REPLACE "\\\\\n" " " FILE_CONTENTS "${FILE_CONTENTS}") string(REGEX REPLACE " +" " " FILE_CONTENTS "${FILE_CONTENTS}") string(REGEX REPLACE ";" "\\\\;" FILE_CONTENTS "${FILE_CONTENTS}") string(REGEX REPLACE "\n" ";" FILE_CONTENTS "${FILE_CONTENTS}") set(${OUTPUT_VARIABLE} ${FILE_CONTENTS} PARENT_SCOPE) endfunction() function(am_target_name AM_FOLDER AM_FILE_NAME AM_OUTPUT) if("${AM_FILE_NAME}" MATCHES "^-l") set(${AM_OUTPUT} ${AM_FILE_NAME} PARENT_SCOPE) return() endif() get_filename_component(AM_FULLPATH "${AM_FILE_NAME}" ABSOLUTE) get_filename_component(AM_FOLDER "${AM_FULLPATH}" PATH) get_filename_component(AM_FOLDER "${AM_FOLDER}" NAME) get_filename_component(AM_FILE_NAME "${AM_FULLPATH}" NAME_WE) string(REGEX REPLACE "^lib" "" AM_FILE_NAME "${AM_FILE_NAME}") string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/(src/)?" "" AM_TARGET_NAME "${AM_FULLPATH}") if("${AM_FOLDER}" STREQUAL "${AM_FILE_NAME}") string(REGEX REPLACE "/[^/]+$" "" AM_TARGET_NAME "${AM_TARGET_NAME}") endif() string(REPLACE "/" "_" AM_TARGET_NAME "${AM_TARGET_NAME}") string(REGEX REPLACE "^src_" "" AM_TARGET_NAME "${AM_TARGET_NAME}") string(REGEX REPLACE "^tests_tests_" "tests_" AM_TARGET_NAME "${AM_TARGET_NAME}") set(${AM_OUTPUT} ${AM_TARGET_NAME} PARENT_SCOPE) endfunction() function(am_add_target AM_TYPE AM_FOLDER AM_FILE AM_SOURCE_FILES AM_LINK_FILES) am_target_name(${AM_FOLDER} ${AM_FILE} AM_TARGET) set(AM_SOURCES "") foreach(AM_SOURCE_FILE ${AM_SOURCE_FILES}) if(NOT AM_SOURCE_FILE STREQUAL "$(EMPTY)") list(APPEND AM_SOURCES ${AM_SOURCE_FILE}) endif() endforeach() if(AM_TYPE STREQUAL "lib") add_library(${AM_TARGET} STATIC ${AM_SOURCES}) else() add_executable(${AM_TARGET} ${AM_SOURCES}) endif() get_target_property(AM_INCLUDE_DIRS ${AM_TARGET} INCLUDE_DIRECTORIES) list(APPEND AM_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/${AM_FOLDER}) set_target_properties(${AM_TARGET} PROPERTIES INCLUDE_DIRECTORIES "${AM_INCLUDE_DIRS}") set(AM_LINK_TARGETS "") foreach(AM_LINK_FILE ${AM_LINK_FILES}) if(NOT "${AM_LINK_FILE}" MATCHES "/lib(glew|lua).la$") if(NOT AM_LINK_FILE STREQUAL "$(EMPTY)" AND NOT AM_LINK_FILE STREQUAL "$(LDADD)") am_target_name(${AM_FOLDER} ${AM_LINK_FILE} AM_LINK_TARGET) list(APPEND AM_LINK_TARGETS ${AM_LINK_TARGET} ${${AM_LINK_TARGET}_LINK_TARGETS}) endif() endif() endforeach() target_link_libraries(${AM_TARGET} ${AM_LINK_TARGETS}) set(${AM_TARGET}_LINK_TARGETS ${AM_LINK_TARGETS} PARENT_SCOPE) endfunction() # Internal Automake -> CMake converter, doing the heavy lifting function(convert_automake_internal AM_INPUT_FILE CMAKE_OUTPUT_FILE) am_read_lines(${AM_INPUT_FILE} AM_VARIABLE) foreach(AM_FILE_LINE ${AM_VARIABLE}) # Recursively handle include directives if("${AM_FILE_LINE}" MATCHES "^include ") string(REGEX REPLACE "^include +" "" AM_INCLUDE_FILE "${AM_FILE_LINE}") file(APPEND "${CMAKE_OUTPUT_FILE}" "# Including ${AM_INCLUDE_FILE}\n") convert_automake_internal(${AM_INCLUDE_FILE} ${CMAKE_OUTPUT_FILE}) continue() endif() string(REGEX REPLACE " *\\+= *" "+=" AM_FILE_LINE "${AM_FILE_LINE}") string(REGEX REPLACE " *= *" "=" AM_FILE_LINE "${AM_FILE_LINE}") string(REGEX REPLACE "^ +" "" AM_FILE_LINE "${AM_FILE_LINE}") string(REGEX REPLACE "^([^=]*[^+])=(.*)$" "set(\\1 \\2)" AM_FILE_LINE "${AM_FILE_LINE}") string(REGEX REPLACE "^([^=]*)\\+=(.*)$" "list(APPEND \\1 \\2)" AM_FILE_LINE "${AM_FILE_LINE}") string(REGEX REPLACE "^if !(.*)$" "if(NOT \\1)" AM_FILE_LINE "${AM_FILE_LINE}") string(REGEX REPLACE "^if (.*)$" "if(\\1)" AM_FILE_LINE "${AM_FILE_LINE}") string(REGEX REPLACE "^else$" "else()" AM_FILE_LINE "${AM_FILE_LINE}") string(REGEX REPLACE "^endif$" "endif()" AM_FILE_LINE "${AM_FILE_LINE}") set(AM_FILE_LINE "#${AM_FILE_LINE}") string(REPLACE "#set(" "set(" AM_FILE_LINE "${AM_FILE_LINE}") string(REPLACE "#list(" "list(" AM_FILE_LINE "${AM_FILE_LINE}") string(REPLACE "#if(" "if(" AM_FILE_LINE "${AM_FILE_LINE}") string(REPLACE "#else(" "else(" AM_FILE_LINE "${AM_FILE_LINE}") string(REPLACE "#endif(" "endif(" AM_FILE_LINE "${AM_FILE_LINE}") # Comment out the gitstamp Automake rule hackery string(REGEX REPLACE "(.*\\$\\([ \t]*eval)" "#\\1" AM_FILE_LINE "${AM_FILE_LINE}") file(APPEND "${CMAKE_OUTPUT_FILE}" "${AM_FILE_LINE}\n") endforeach() endfunction() function(am_find_directories INPUT_PATH OUTPUT_LIST) if ("${INPUT_PATH}" MATCHES "/") string(REGEX REPLACE "/[^/]*$" "" INPUT_DIRECTORY "${INPUT_PATH}") list(APPEND "${OUTPUT_LIST}" "${INPUT_DIRECTORY}") endif() set(${OUTPUT_LIST} "${${OUTPUT_LIST}}" PARENT_SCOPE) endfunction() # Set target CXXFLAGS, by parsing for special values function(am_set_flags TARGET FLAGS_LIST) list(LENGTH FLAGS_LIST FLAGS_COUNT) set(FLAGS_MISC) set(FLAGS_DEFINE) set(FLAGS_INCLUDES) set(FLAGS_INCLUDES_SYSTEM) set(i 0) while(${i} LESS ${FLAGS_COUNT}) list(GET FLAGS_LIST ${i} FLAG) if("${FLAG}" MATCHES "^-D$") math(EXPR i "${i} + 1") list(GET FLAGS_LIST ${i} FLAG) list(APPEND FLAGS_DEFINE "${FLAG}") elseif("${FLAG}" MATCHES "^-D") string(REGEX REPLACE "^-D" "" FLAG "${FLAG}") list(APPEND FLAGS_DEFINE "${FLAG}") elseif("${FLAG}" STREQUAL "-isystem") math(EXPR i "${i} + 1") list(GET FLAGS_LIST ${i} FLAG) list(APPEND FLAGS_INCLUDES_SYSTEM "${FLAG}") elseif("${FLAG}" MATCHES "^-I$") math(EXPR i "${i} + 1") list(GET FLAGS_LIST ${i} FLAG) list(APPEND FLAGS_INCLUDES "${FLAG}") elseif("${FLAG}" MATCHES "^-I") string(REGEX REPLACE "^-I" "" FLAG "${FLAG}") list(APPEND FLAGS_INCLUDES "${FLAG}") else() list(APPEND FLAGS_MISC "${FLAG}") endif() math(EXPR i "${i} + 1") endwhile() string(REPLACE ";" " " FLAGS_MISC "${FLAGS_MISC}") set_target_properties(${TARGET} PROPERTIES APPEND_STRING PROPERTY COMPILE_FLAGS "${FLAGS_MISC}") get_target_property(TARGET_SOURCES ${TARGET} SOURCES) foreach(TARGET_SOURCE ${TARGET_SOURCES}) set_source_files_properties(${TARGET_SOURCE} PROPERTIES APPEND PROPERTY COMPILE_DEFINITIONS "${FLAGS_DEFINE}") endforeach() target_include_directories(${TARGET} PUBLIC ${FLAGS_INCLUDES}) target_include_directories(${TARGET} SYSTEM PUBLIC ${FLAGS_INCLUDES_SYSTEM}) endfunction() # Create the output file, and start the conversion function(convert_automake AM_INPUT_FILE CMAKE_OUTPUT_FILE) file(WRITE "${CMAKE_OUTPUT_FILE}" "# Autogenerated file, do not edit!\n") convert_automake_internal(${AM_INPUT_FILE} ${CMAKE_OUTPUT_FILE}) endfunction() function(parse_automake AM_FILE_NAME) set(srcdir ${PROJECT_SOURCE_DIR}) get_filename_component(AM_FOLDER ${AM_FILE_NAME} PATH) if(NOT EXISTS ${AM_FOLDER}) file(MAKE_DIRECTORY ${AM_FOLDER}) endif() # Convert this Automake file into a CMake file and include it set(CMAKE_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${AM_FILE_NAME}.cmake") convert_automake(${AM_FILE_NAME} ${CMAKE_OUTPUT_FILE}) include(${CMAKE_OUTPUT_FILE}) set(AM_TARGETS) set(AM_DIRECTORIES) # Search for convenience libraries, creating CMake targets set(AM_STATIC_LIBRARIES) foreach(AM_FILE ${noinst_LTLIBRARIES} ${check_LTLIBRARIES}) string(REPLACE "." "_" AM_NAME "${AM_FILE}") string(REPLACE "/" "_" AM_NAME "${AM_NAME}") am_add_target(lib ${AM_FOLDER} ${AM_FILE} "${${AM_NAME}_SOURCES}" "${${AM_NAME}_LIBADD}") am_target_name(${AM_FOLDER} ${AM_FILE} AM_TARGET) set(${AM_TARGET}_LINK_TARGETS ${${AM_TARGET}_LINK_TARGETS} PARENT_SCOPE) am_set_flags(${AM_TARGET} "${${AM_NAME}_CXXFLAGS}") am_find_directories("${AM_FILE}" AM_DIRECTORIES) list(APPEND AM_TARGETS ${AM_TARGET}) list(APPEND AM_STATIC_LIBRARIES ${AM_TARGET}) endforeach() # Search for programs, creating CMake targets set(AM_PROGRAMS) foreach(AM_FILE ${bin_PROGRAMS} ${check_PROGRAMS}) string(REPLACE "." "_" AM_NAME "${AM_FILE}") string(REPLACE "/" "_" AM_NAME "${AM_NAME}") am_add_target(bin ${AM_FOLDER} ${AM_FILE} "${${AM_NAME}_SOURCES}" "${${AM_NAME}_LDADD}") am_target_name(${AM_FOLDER} ${AM_FILE} AM_TARGET) set(${AM_TARGET}_LINK_TARGETS ${${AM_TARGET}_LINK_TARGETS} PARENT_SCOPE) am_set_flags(${AM_TARGET} "${${AM_NAME}_CXXFLAGS}") am_find_directories(${AM_FILE} AM_DIRECTORIES) list(APPEND AM_TARGETS ${AM_TARGET}) list(APPEND AM_PROGRAMS ${AM_TARGET}) endforeach() set(AM_MAN1_MANS) foreach(AM_MAN ${dist_man1_MANS}) list(APPEND AM_MAN1_MANS ${AM_MAN}) endforeach() set(AM_MAN6_MANS) foreach(AM_MAN ${dist_man6_MANS}) list(APPEND AM_MAN6_MANS ${AM_MAN}) endforeach() set(AM_DOCS) foreach(AM_DOC ${dist_doc_DATA}) list(APPEND AM_DOCS ${AM_DOC}) endforeach() if(AM_DIRECTORIES) list(REMOVE_DUPLICATES AM_DIRECTORIES) endif() set(AM_TARGETS ${AM_TARGETS} PARENT_SCOPE) set(AM_STATIC_LIBRARIES ${AM_STATIC_LIBRARIES} PARENT_SCOPE) set(AM_PROGRAMS ${AM_PROGRAMS} PARENT_SCOPE) set(AM_MAN1_MANS ${AM_MAN1_MANS} PARENT_SCOPE) set(AM_MAN6_MANS ${AM_MAN6_MANS} PARENT_SCOPE) set(AM_DOCS ${AM_DOCS} PARENT_SCOPE) set(AM_DIRECTORIES ${AM_DIRECTORIES} PARENT_SCOPE) endfunction() xoreos-tools-0.0.5/cmake/CMakeUninstall.cmake000066400000000000000000000051221331663051500211300ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . # Code taken from https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake. if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") exec_program( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") endif(NOT "${rm_retval}" STREQUAL 0) else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File $ENV{DESTDIR}${file} does not exist.") endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") get_filename_component(file_dir "$ENV{DESTDIR}${file}" DIRECTORY) file(GLOB_RECURSE DIR_FILES ${file_dir}/*) list(LENGTH DIR_FILES DIR_FILES_LEN) if(DIR_FILES_LEN EQUAL 0 AND EXISTS ${file_dir} AND IS_DIRECTORY ${file_dir}) message(STATUS "Removing Directory \"${file_dir}\"") exec_program( "/usr/bin/cmake" ARGS "-E remove_directory \"${file_dir}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing ${file_dir}") endif() endif() endforeach(file) xoreos-tools-0.0.5/cmake/FindIconv.cmake000066400000000000000000000046171331663051500201450ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . # https://github.com/onyx-intl/cmake_modules/blob/master/FindIconv.cmake # # - Try to find Iconv # Once done this will define # # ICONV_FOUND - system has Iconv # ICONV_INCLUDE_DIR - the Iconv include directory # ICONV_LIBRARIES - Link these to use Iconv # ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const # include(CheckCXXSourceCompiles) IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) # Already in cache, be silent SET(ICONV_FIND_QUIETLY TRUE) ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) FIND_PATH(ICONV_INCLUDE_DIR iconv.h) FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c) IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) SET(ICONV_FOUND TRUE) SET(ICONV_INCLUDE_DIRS ${ICONV_INCLUDE_DIR}) ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES}) IF(ICONV_FOUND) check_cxx_source_compiles(" #include int main(){ iconv_t conv = 0; const char* in = 0; size_t ilen = 0; char* out = 0; size_t olen = 0; iconv(conv, &in, &ilen, &out, &olen); return 0; } " ICONV_SECOND_ARGUMENT_IS_CONST ) ENDIF(ICONV_FOUND) set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) IF(ICONV_FOUND) IF(NOT ICONV_FIND_QUIETLY) MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") ENDIF(NOT ICONV_FIND_QUIETLY) ELSE(ICONV_FOUND) IF(Iconv_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Could not find Iconv") ENDIF(Iconv_FIND_REQUIRED) ENDIF(ICONV_FOUND) MARK_AS_ADVANCED( ICONV_INCLUDE_DIR ICONV_LIBRARIES ICONV_SECOND_ARGUMENT_IS_CONST ) xoreos-tools-0.0.5/cmake/SetCheckCompilerFlag.cmake000066400000000000000000000031621331663051500222360ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) function(set_check_compiler_flag_c FLAG) CHECK_C_COMPILER_FLAG(${FLAG} hasC${FLAG}) if(hasC${FLAG}) if(ARGN) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARGN}" PARENT_SCOPE) else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAG}" PARENT_SCOPE) endif() endif() endfunction() function(set_check_compiler_flag_cxx FLAG) CHECK_CXX_COMPILER_FLAG(${FLAG} hasCXX${FLAG}) if(hasCXX${FLAG}) if(ARGN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGN}" PARENT_SCOPE) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}" PARENT_SCOPE) endif() endif() endfunction() macro(set_check_compiler_flag_c_cxx FLAG) set_check_compiler_flag_c(${FLAG} ${ARGN}) set_check_compiler_flag_cxx(${FLAG} ${ARGN}) endmacro() xoreos-tools-0.0.5/cmake/toolchain/000077500000000000000000000000001331663051500172345ustar00rootroot00000000000000xoreos-tools-0.0.5/cmake/toolchain/i686-windows-mingw.cmake000066400000000000000000000035311331663051500235430ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . if(CMAKE_TOOLCHAIN_FILE) # touch toolchain variable to suppress "unused variable" warning endif() # the name of the target operating system set(CMAKE_SYSTEM_NAME Windows) # Choose an appropriate compiler prefix set(CMAKE_TOOLCHAIN_PREFIX "i686-w64-mingw32") # which compilers to use for C and C++ find_program(CMAKE_RC_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-windres) find_program(CMAKE_C_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-gcc) find_program(CMAKE_CXX_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-g++) find_program(CMAKE_ASM_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-as) # here is the target environment located set(CMAKE_FIND_ROOT_PATH /usr/${CMAKE_TOOLCHAIN_PREFIX} /usr/local/${CMAKE_TOOLCHAIN_PREFIX}) # adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_CROSS_COMPILING TRUE) xoreos-tools-0.0.5/cmake/toolchain/x86_64-windows-mingw.cmake000066400000000000000000000035331331663051500240070ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . if(CMAKE_TOOLCHAIN_FILE) # touch toolchain variable to suppress "unused variable" warning endif() # the name of the target operating system set(CMAKE_SYSTEM_NAME Windows) # Choose an appropriate compiler prefix set(CMAKE_TOOLCHAIN_PREFIX "x86_64-w64-mingw32") # which compilers to use for C and C++ find_program(CMAKE_RC_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-windres) find_program(CMAKE_C_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-gcc) find_program(CMAKE_CXX_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-g++) find_program(CMAKE_ASM_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-as) # here is the target environment located set(CMAKE_FIND_ROOT_PATH /usr/${CMAKE_TOOLCHAIN_PREFIX} /usr/local/${CMAKE_TOOLCHAIN_PREFIX}) # adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_CROSS_COMPILING TRUE) xoreos-tools-0.0.5/configure.ac000066400000000000000000000160171331663051500164670ustar00rootroot00000000000000dnl xoreos-tools - Tools to help with xoreos development dnl dnl xoreos-tools is the legal property of its developers, whose names dnl can be found in the AUTHORS file distributed with this source dnl distribution. dnl dnl xoreos-tools is free software; you can redistribute it and/or dnl modify it under the terms of the GNU General Public License dnl as published by the Free Software Foundation; either version 3 dnl of the License, or (at your option) any later version. dnl dnl xoreos-tools is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with xoreos-tools. If not, see . AC_PREREQ([2.65]) AC_INIT([xoreos-tools],[0.0.5],[xoreos-devel@xoreos.org],[xoreos-tools],[https://xoreos.org/]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([config.h.in]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([1.11 foreign -Wall -Wno-portability no-dist-gzip dist-xz subdir-objects]) dnl Support silent build rules. Disable by either passing dnl --disable-silent-rules to configure or passing V=1 to make AM_SILENT_RULES([yes]) dnl If AM_PROG_AR exists, call it, to shut up a libtool warning (and make it more portable, I guess?) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) dnl libtool LT_PREREQ([2.2]) LT_INIT([disable-shared]) dnl We're C++ AC_PROG_CXX AC_LANG([C++]) dnl We want a make install AC_PROG_INSTALL dnl Standard C++ AC_HEADER_STDC dnl Endianness AC_C_BIGENDIAN dnl Special variables of the size of pointers AC_TYPE_INTPTR_T AC_TYPE_UINTPTR_T dnl Check the sizes of integer types AC_CHECK_SIZEOF([char]) AC_CHECK_SIZEOF([short]) AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([long long]) AC_CHECK_SIZEOF([void *]) dnl math library and special float functions AC_CHECK_LIB([m], [cos]) AC_CHECK_FUNCS([fabs]) AC_CHECK_FUNCS([fmin]) AC_CHECK_FUNCS([fmax]) AC_CHECK_FUNCS([fabsf]) AC_CHECK_FUNCS([fminf]) AC_CHECK_FUNCS([fmaxf]) dnl String to integer/float conversion functions AC_CHECK_FUNCS([strtoll]) AC_CHECK_FUNCS([strtoull]) AC_CHECK_FUNCS([strtof]) dnl Check for -ggdb support GGDB="" AX_CHECK_COMPILER_FLAGS_VAR([C++], [GGDB], [-ggdb]) AC_SUBST(GGDB) dnl --with-werror AC_ARG_WITH([werror], [AS_HELP_STRING([--with-werror], [Compile with -Werror @<:@default=no@:>@])], [], [with_werror=no]) WERROR="" if test "x$with_werror" = "xyes"; then AX_CHECK_COMPILER_FLAGS_VAR([C++], [WERROR], [-Werror]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WERROR], [-Werror=unused-but-set-variable]) fi AC_SUBST(WERROR) dnl Compiler warning flags AC_ARG_WITH([warnings], [AS_HELP_STRING([--without-warnings], [Compile without extra warnings @<:@default=no@:>@])], [], [with_warnings=yes]) WARN="" if test "x$with_warnings" = "xyes"; then WARN="-Wall" dnl Extra warnings valid for both C and C++ AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wignored-qualifiers]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wpointer-arith]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wshadow]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wsign-compare]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wtype-limits]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wuninitialized]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wunused-parameter]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wunused-but-set-parameter]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wduplicated-cond]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wduplicated-branches]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wlogical-op]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wshift-negative-value]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wshift-overflow=2]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wimplicit-fallthrough]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wvla]) dnl Extra warnings valid for C++ AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wnon-virtual-dtor]) fi dnl Disable warnings about hiding virtual functions from a base class. We don't care AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Woverloaded-virtual], [-Wno-overloaded-virtual]) dnl Disable warnings about the long long type. We need it AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wlong-long], [-Wno-long-long]) AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wc++11-long-long], [-Wno-c++11-long-long]) dnl clang is far too trigger-happy on this warning, so let's disable it AX_CHECK_COMPILER_FLAGS_VAR([C++], [WARN], [-Wundefined-var-template], [-Wno-undefined-var-template]) AC_SUBST(WARN) dnl C++ dialect AC_ARG_WITH([std], [AS_HELP_STRING([--with-std], [Compile with specifying the C++ standard to follow @<:@default=no@:>@])], [], [with_std=no]) STD="" if test "x$with_std" = "xyes"; then AX_CHECK_COMPILER_FLAGS_VAR([C++], [STD], [-std=c++03]) fi AC_SUBST(STD) dnl Link-time optimization AC_ARG_WITH([lto], [AS_HELP_STRING([--with-lto], [Compile with link-time optimization @<:@default=no@:>@])], [], [with_lto=no]) LTO="" if test "x$with_lto" = "xyes"; then AX_CHECK_COMPILER_FLAGS_VAR([C++], [LTO], [-flto]) fi AC_SUBST(LTO) dnl Optimize against local CPU AC_ARG_WITH([native], [AS_HELP_STRING([--with-native], [Pass -march=native to the compiler to optimize directly against the local CPU instead of generating a more generic build @<:@default=no@:>@])], [], [with_native=no]) NATIVE="" if test "x$with_native" = "xyes"; then AX_CHECK_COMPILER_FLAGS_VAR([C++], [NATIVE], [-march=native]) fi AC_SUBST(NATIVE) dnl Release version number AC_ARG_WITH([release], [AS_HELP_STRING([--with-release=VER], [Set the version suffix to VER instead of the git revision. If no VER is given, do not add a version suffix at all])], [], [with_release=no]) if test "x$with_release" != "xno"; then AC_DEFINE([XOREOS_RELEASE], 1, [Define to 1 if we are in release version mode]) if test "x$with_release" != "xyes"; then AC_DEFINE_UNQUOTED([XOREOS_DISTRO], ["+$with_release"], [Release version suffix]) fi fi dnl General purpose libraries AX_CHECK_ICONV( , AC_MSG_ERROR([No useable iconv() function found!])) AX_CHECK_ZLIB(1, 2, 3, 0, , AC_MSG_ERROR([zlib(>= 1.2.3) is required and could not be found!])) AX_CHECK_XML2(2, 8, 0, , AC_MSG_ERROR([libxml2(>= 2.8.0) is required and could not be found!])) dnl Boost BOOST_REQUIRE(1.53.0) BOOST_UTILITY BOOST_STRING_ALGO BOOST_SYSTEM BOOST_FILESYSTEM BOOST_REGEX BOOST_HASH BOOST_FUNCTION BOOST_BIND BOOST_UUID BOOST_SMART_PTR BOOST_SCOPE_EXIT BOOST_ATOMIC BOOST_LOCALE dnl pthread AX_PTHREAD() AM_CONDITIONAL([HAVE_PTHREAD], [test x"$ax_pthread_ok" = xyes]) dnl Extra flags case "$target" in *darwin*) XOREOSTOOLS_CFLAGS="-DUNIX -DMACOSX" XOREOSTOOLS_LIBS="" AM_CONDITIONAL(WIN32, false) ;; *mingw*) XOREOSTOOLS_CFLAGS="-mconsole" XOREOSTOOLS_LIBS="" AM_CONDITIONAL(WIN32, true) ;; *) XOREOSTOOLS_CFLAGS="-DUNIX" XOREOSTOOLS_LIBS="" AM_CONDITIONAL(WIN32, false) ;; esac; AC_SUBST(XOREOSTOOLS_CFLAGS) AC_SUBST(XOREOSTOOLS_LIBS) AC_CONFIG_FILES([Makefile]) AC_OUTPUT xoreos-tools-0.0.5/dists/000077500000000000000000000000001331663051500153225ustar00rootroot00000000000000xoreos-tools-0.0.5/dists/arch/000077500000000000000000000000001331663051500162375ustar00rootroot00000000000000xoreos-tools-0.0.5/dists/arch/PKGBUILD000066400000000000000000000013061331663051500173630ustar00rootroot00000000000000# Maintainer: Sven Hesse pkgname=xoreos-tools-git _gitname=xoreos-tools pkgver=0.0.5.r0.g06f686c pkgrel=1 pkgdesc="Tools to help with xoreos development" arch=('i686' 'x86_64') url="https://xoreos.org/" license=('GPL3') depends=('zlib' 'libxml2' 'boost' 'boost-libs') makedepends=() source=('git://github.com/xoreos/xoreos-tools.git') md5sums=('SKIP') pkgver() { cd "$srcdir/$_gitname" git describe --long --match desc/\* | cut -d '/' -f 2- | sed -e 's/\(.*\)-\([^-]*\)-\([^-]*\)/\1.r\2.\3/' } build() { cd "$srcdir/$_gitname" ./autogen.sh ./configure --with-release=xArch --with-lto --prefix=/usr make } package() { cd "$srcdir/$_gitname" make DESTDIR="$pkgdir/" install } xoreos-tools-0.0.5/dists/debian/000077500000000000000000000000001331663051500165445ustar00rootroot00000000000000xoreos-tools-0.0.5/dists/debian/changelog000066400000000000000000000010621331663051500204150ustar00rootroot00000000000000xoreos-tools (0.0.5-1) unstable; urgency=low * New upstream release -- Sven Hesse Tue, 03 Jul 2018 00:00:00 +0200 xoreos-tools (0.0.4-1) unstable; urgency=low * New upstream release -- Sven Hesse Mon, 01 Feb 2016 00:00:00 +0100 xoreos-tools (0.0.3-1) unstable; urgency=low * New upstream release -- Sven Hesse Wed, 30 Sep 2015 00:00:00 +0200 xoreos-tools (0.0.2-1) unstable; urgency=low * Initial release -- Sven Hesse Mon, 27 Jul 2015 09:34:21 +0200 xoreos-tools-0.0.5/dists/debian/compat000066400000000000000000000000021331663051500177420ustar00rootroot000000000000009 xoreos-tools-0.0.5/dists/debian/control000066400000000000000000000013641331663051500201530ustar00rootroot00000000000000Source: xoreos-tools Section: misc Priority: optional Maintainer: Sven Hesse Build-Depends: debhelper (>= 9), dh-autoreconf, autotools-dev, autoconf (>= 2.65), gettext, zlib1g-dev (>= 1:1.2.3.4), libxml2-dev (>= 2.8.0), libboost-dev (>= 1.53), libboost-atomic-dev (>= 1.53), libboost-filesystem-dev (>= 1.53), libboost-locale-dev (>= 1.53), libboost-regex-dev (>= 1.53), libboost-system-dev (>= 1.53) Standards-Version: 3.9.6 Homepage: https://xoreos.org/ Package: xoreos-tools Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Tools to help with xoreos development A collection of tools to help with the reverse-engineering of BioWare's Aurora engine games. . xoreos-tools is part of the xoreos project. xoreos-tools-0.0.5/dists/debian/copyright000066400000000000000000000434441331663051500205100ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: xoreos-tools Source: https://xoreos.org/ Files: * Copyright: 2010-2018 The xoreos Team License: GPL-3.0+ Comment: See list of copyright holders and upstream authors in "/usr/share/doc/xoreos-tools/AUTHORS". Files: debian/* dists/debian/* Copyright: 2015-2016 Sven Hesse License: GPL-3.0+ Files: dists/arch/PKGBUILD Copyright: 2015-2016 Sven Hesse License: GPL-3.0+ Files: dists/fedora/build-from-git.sh dists/fedora/xoreos-tools.spec Copyright: 2016 Ben Rosser License: GPL-3.0+ Files: CODE_OF_CONDUCT Copyright: 2014-2016 Coraline Ada Ehmke License: Expat Files: m4/boost.m4 Copyright: 2007-2011, 2014 Benoit Sigoure License: GPL-3.0+ Files: m4/ax_check_compiler_flags.m4 Copyright: 2005 Steven G. Johnson 2005 Matteo Frigo License: GPL-1.0+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. . As a special exception, the respective Autoconf Macro's copyright owner gives unlimited permission to copy, distribute and modify the configure scripts that are the output of Autoconf when processing the Macro. You need not follow the terms of the GNU General Public License when using or distributing such scripts Files: m4/lib-ld.m4 Copyright: 1996-2003, 2009-2015 Free Software Foundation, Inc. License: This file is free software; the Free Software Foundation gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. Files: m4/lib-link.m4 Copyright: 2001-2015 Free Software Foundation, Inc. License: This file is free software; the Free Software Foundation gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. Files: m4/lib-prefix.m4 Copyright: 2001-2005 Free Software Foundation, Inc. License: This file is free software; the Free Software Foundation gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. Files: m4/iconv.m4 Copyright: 2000-2002, 2007-2014 Free Software Foundation, Inc. License: This file is free software; the Free Software Foundation gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. Files: m4/ax_check_iconv.m4 m4/ax_check_zlib.m4 Copyright: 2013 Sven Hesse License: CC0-1.0 Files: m4/ax_check_compiler_flags_var.m4 m4/ax_check_xml2.m4 Copyright: 2015 Sven Hesse License: CC0-1.0 Files: utf8cpp/utf8.h utf8cpp/utf8/*.h Copyright: 2006 Nemanja Trifunovic License: BSL-1.0 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: . The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. . 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Files: src/common/system.h src/common/endianness.h src/common/util.h src/common/noncopyable.h src/common/singleton.h src/common/readstream.h src/common/readstream.cpp src/common/writestream.h src/common/writestream.cpp src/common/memreadstream.h src/common/memreadstream.cpp src/common/memwritestream.cpp Copyright: 2001-2010 The ScummVM Project 2010-2015 The xoreos Team License: GPL-2.0+, GPL-3.0+ Files: src/images/tga.h src/images/tga.cpp Copyright: 2010-2015 The xoreos Team 2012 The ScummVM Project License: GPL-2.0+, GPL-3.0+ Files: src/common/md5.cpp Copyright: 2001 Alexander Peslyak 2015 The xoreos Team License: This software was written by Alexander Peslyak in 2001. No copyright is claimed, and the software is hereby placed in the public domain. In case this attempt to disclaim copyright and place the software in the public domain is deemed null and void, then the software is Copyright (c) 2001 Alexander Peslyak and it is hereby released to the general public under the following terms: . Redistribution and use in source and binary forms, with or without modification, are permitted. . There's ABSOLUTELY NO WARRANTY, express or implied. Files: src/common/blowfish.cpp Copyright: 2006-2015 ARM Limited 2015 The xoreos Team License: Apache-2, GPL-3.0+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. . On Debian systems, the complete text of the Apache License 2.0 can be found in "/usr/share/common-licenses/Apache-2" Comment: Originally found in mbed TLS. Files: src/common/hash.h Copyright: 2012-2015 The xoreos Team License: GPL-3.0+ Comment: Includes an implementation of the CRC32 hash function, based on an implementation by Gary S. Brown: . COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or code or tables extracted from it, as desired without restriction. Files: src/images/ncgr.cpp src/images/nclr.cpp Copyright: 2011 pleoNeX 2015 The xoreos Team License: GPL-3.0+ Files: tests/googletest/src/*.h tests/googletest/src/*.cc tests/googletest/include/gtest/*.h tests/googletest/include/gtest/internal/*.h tests/googletest/include/gtest/internal/custom/*.h Copyright: 2003, 2005-2009, 2015 Google Inc. License: BSD-3-clause License: GPL-2.0+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-2". License: GPL-3.0+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". License: Expat 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. Comment: This license also known as "MIT/X11 (BSD like)" or "MIT" however FSF consider "MIT" labelling ambiguous and copyright-format specification recommend to label such license as "Expat". License: CC0-1.0 CC0 1.0 Universal . CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. . Statement of Purpose . The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). . Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. . For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. . 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: . i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. . 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. . 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. . 4. Limitations and Disclaimers. . a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the author may be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. xoreos-tools-0.0.5/dists/debian/rules000077500000000000000000000012761331663051500176320ustar00rootroot00000000000000#!/usr/bin/make -f # See debhelper(7) (uncomment to enable) # output every command that modifies files on the build system. #export DH_VERBOSE = 1 # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/default.mk PACKAGE = $(shell dh_listpackages) TMP = $(CURDIR)/debian/$(PACKAGE) # main packaging script based on dh7 syntax %: dh $@ --with autoreconf override_dh_auto_configure: dh_auto_configure -- --with-release=xDebian override_dh_auto_install: dh_auto_install # These files are redundant for Debian packages rm --verbose $(TMP)/usr/share/doc/xoreos-tools/COPYING rm --verbose $(TMP)/usr/share/doc/xoreos-tools/ChangeLog xoreos-tools-0.0.5/dists/debian/source/000077500000000000000000000000001331663051500200445ustar00rootroot00000000000000xoreos-tools-0.0.5/dists/debian/source/format000066400000000000000000000000141331663051500212520ustar00rootroot000000000000003.0 (quilt) xoreos-tools-0.0.5/dists/debian/xoreos-tools.lintian-overrides000066400000000000000000000000701331663051500245760ustar00rootroot00000000000000# Yeah, we don't care. new-package-should-close-itp-bug xoreos-tools-0.0.5/dists/fedora/000077500000000000000000000000001331663051500165625ustar00rootroot00000000000000xoreos-tools-0.0.5/dists/fedora/build-from-git.sh000077500000000000000000000020641331663051500217440ustar00rootroot00000000000000#!/bin/bash # This is a helper script to update the Release tag of the specfile # and then invoke rpmbuild --build-in-place with the correct options # to build from the root of the git checkout. # You need rpmbuild to build the rpm. # Thanks to StackOverflow: # https://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in RPM_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" XOREOS_ROOT=`git rev-parse --show-toplevel` SPEC_NAME=${RPM_DIR}/xoreos-tools.spec # Compute the release snapshot, create a temporary spec. Also redine _rpmdir SNAPSHOT=`date +"%Y%m%d"` sed "s,\%global snapshot .*,\%global snapshot ${SNAPSHOT}git," < ${SPEC_NAME} > ${SPEC_NAME}.tmp sed "1s,^,\%define _rpmdir ${RPM_DIR}\n," -i ${SPEC_NAME}.tmp # Create a buildroot directory. mkdir -p ${RPM_DIR}/buildroot # Invoke rpmbuild from the root of the git repo (so --build-in-place works). # Also set the --buildroot and -- cd ${XOREOS_ROOT} rpmbuild --build-in-place --rmspec --buildroot ${RPM_DIR}/buildroot -bb ${SPEC_NAME}.tmp rm -rf ${RPM_DIR}/buildroot xoreos-tools-0.0.5/dists/fedora/xoreos-tools.spec000066400000000000000000000072021331663051500221140ustar00rootroot00000000000000# If you want to build the current git checkout, run "build-from-git.sh". # If you want to build the last stable release of xoreos instead, # build from this specfile directly. # Globals, overridden by build script. %global snapshot 0 Name: xoreos-tools Version: 0.0.5 # This is a bit ugly but it works. %if "%{snapshot}" == "0" Release: 1%{?dist} %else Release: 1.%{snapshot}%{?dist} %endif Summary: Tools to help the development of xoreos License: GPLv3 URL: https://xoreos.org/ Source0: https://github.com/xoreos/xoreos-tools/releases/download/%{version}/%{name}-%{version}.tar.gz BuildRequires: zlib-devel, libxml2-devel BuildRequires: libtool, gettext # Boost dependencies. BuildRequires: boost-devel, boost-system, boost-filesystem, boost-atomic, BuildRequires: boost-regex, boost-locale #Requires: %description A collection of tools to help with the reverse-engineering of BioWare's Aurora engine games. xoreos-tools is part of the xoreos project; please see the xoreos website and its GitHub repositories for details, especially the main README.md. Currently, the following tools are included: * gff2xml: Convert BioWare GFF to XML * tlk2xml: Convert BioWare TLK to XML * ssf2xml: Convert BioWare SSF to XML * xml2tlk: Convert XML back to BioWare TLK * xml2ssf: Convert XML back to BioWare SSF * convert2da: Convert BioWare 2DA/GDA to 2DA/CSV * erf: Create BioWare ERF archives * fixpremiumgff: Repair BioWare GFF files in NWN premium module HAKs * unerf: Extract BioWare ERF archives * unherf: Extract BioWare HERF archives * unrim: Extract BioWare RIM archives * unnds: Extract Nintendo DS roms * unnsbtx: Extract Nintendo NSBTX textures into TGA images * unkeybif: Extract BioWare KEY/BIF archives * desmall: Decompress "small" (Nintendo DS LZSS, types 0x00 and 0x10) files * xoreostex2tga: Convert BioWare's texture formats into TGA * nbfs2tga: Convert Nintendo's raw NBFS images into TGA * ncgr2tga: Convert Nintendo's NCGR images into TGA * cbgt2tga: Convert CBGT images into TGA * cdpth2tga: Convert CDPTH depth images into TGA * ncsdis: Disassemble NWScript bytecode %prep %setup -q %build ./autogen.sh %configure --with-release=xFedora # When building in place we want to do a make clean. make clean make %{?_smp_mflags} %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} # We'll get the documentation manually. rm %{buildroot}%{_pkgdocdir}/* %files # Scripts. %{_bindir}/cbgt2tga %{_bindir}/cdpth2tga %{_bindir}/convert2da %{_bindir}/desmall %{_bindir}/erf %{_bindir}/fixpremiumgff %{_bindir}/gff2xml %{_bindir}/nbfs2tga %{_bindir}/ncgr2tga %{_bindir}/ncsdis %{_bindir}/tlk2xml %{_bindir}/ssf2xml %{_bindir}/unerf %{_bindir}/unherf %{_bindir}/unkeybif %{_bindir}/unnds %{_bindir}/unnsbtx %{_bindir}/unrim %{_bindir}/xml2tlk %{_bindir}/xml2ssf %{_bindir}/xoreostex2tga # man pages. %{_mandir}/man1/cbgt2tga.1* %{_mandir}/man1/cdpth2tga.1* %{_mandir}/man1/convert2da.1* %{_mandir}/man1/desmall.1* %{_mandir}/man1/erf.1* %{_mandir}/man1/fixpremiumgff.1.* %{_mandir}/man1/gff2xml.1.* %{_mandir}/man1/nbfs2tga.1.* %{_mandir}/man1/ncgr2tga.1.* %{_mandir}/man1/ncsdis.1.* %{_mandir}/man1/tlk2xml.1.* %{_mandir}/man1/ssf2xml.1.* %{_mandir}/man1/unerf.1.* %{_mandir}/man1/unherf.1.* %{_mandir}/man1/unkeybif.1.* %{_mandir}/man1/unnds.1.* %{_mandir}/man1/unnsbtx.1.* %{_mandir}/man1/unrim.1.* %{_mandir}/man1/xml2tlk.1.* %{_mandir}/man1/xml2ssf.1.* %{_mandir}/man1/xoreostex2tga.1.* %doc *.md AUTHORS ChangeLog TODO %license COPYING %changelog * Tue Jul 03 2018 Sven Hesse 0.0.5-1 - New upstream release. * Mon Feb 15 2016 Ben Rosser 0.0.4-1 - Initial package. xoreos-tools-0.0.5/dists/rules.mk000066400000000000000000000024321331663051500170060ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . # Our distribution files. # Arch Linux EXTRA_DIST += \ dists/arch/PKGBUILD \ $(EMPTY) # Debian EXTRA_DIST += \ dists/debian/changelog \ dists/debian/compat \ dists/debian/control \ dists/debian/copyright \ dists/debian/rules \ dists/debian/xoreos-tools.lintian-overrides \ dists/debian/source/format \ $(EMPTY) # Fedora EXTRA_DIST += \ dists/fedora/build-from-git.sh \ dists/fedora/xoreos-tools.spec \ $(EMPTY) xoreos-tools-0.0.5/doc/000077500000000000000000000000001331663051500147415ustar00rootroot00000000000000xoreos-tools-0.0.5/doc/LICENSE.GPLv2000066400000000000000000000432541331663051500166470ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. xoreos-tools-0.0.5/doc/rules.mk000066400000000000000000000023171331663051500164270ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . # Documentation for xoreos-tools # Licenses and credits dist_doc_DATA += \ COPYING \ AUTHORS \ $(EMPTY) EXTRA_DIST += \ doc/LICENSE.GPLv2 \ $(EMPTY) # User documentation dist_doc_DATA += \ ChangeLog \ NEWS.md \ TODO \ README.md \ $(EMPTY) # Documents for contributors dist_doc_DATA += \ CONTRIBUTING.md \ CODE_OF_CONDUCT.md \ $(EMPTY) xoreos-tools-0.0.5/m4/000077500000000000000000000000001331663051500145145ustar00rootroot00000000000000xoreos-tools-0.0.5/m4/ax_check_compiler_flags.m4000066400000000000000000000034171331663051500215760ustar00rootroot00000000000000#serial 1000 dnl @synopsis AX_CHECK_COMPILER_FLAGS(FLAGS, EXTRAFLAGS, [ACTION-SUCCESS], [ACTION-FAILURE]) dnl dnl @summary check whether FLAGS are accepted by the compiler dnl dnl Check whether the given compiler FLAGS work with the current dnl language's compiler, or whether they give an error. (Warnings, dnl however, are ignored.) dnl dnl EXTRAFLAGS will be added for the check, and can be used to, for dnl example, for warnings to produce an error. dnl dnl ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on dnl success/failure. dnl dnl @category Misc dnl @author Steven G. Johnson and Matteo Frigo. dnl @version 2005-05-30 dnl @license GPLWithACException AC_DEFUN([AX_CHECK_COMPILER_FLAGS], [AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX AC_MSG_CHECKING([whether _AC_LANG compiler accepts $1]) dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname: AS_LITERAL_IF([$1], [AC_CACHE_VAL(AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1), [ ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$1 $2" AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes, AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no) _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])], [ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$1 $2" AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes, eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no) _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS]) eval ax_check_compiler_flags=$AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1) AC_MSG_RESULT($ax_check_compiler_flags) if test "x$ax_check_compiler_flags" = xyes; then m4_default([$3], :) else m4_default([$4], :) fi ])dnl AX_CHECK_COMPILER_FLAGS xoreos-tools-0.0.5/m4/ax_check_compiler_flags_var.m4000066400000000000000000000017401331663051500224430ustar00rootroot00000000000000#serial 1000 dnl @synopsis AX_CHECK_COMPILER_FLAGS_VAR(language, variable, flag-to-test, flag-to-use) dnl dnl @summary Check whether the compiler for this language accepts flag-to-test, dnl and add flag-to-add to the variable if it does. flag-to-test and dnl flag-to-add can be different, because a compiler might allow dnl a stray -Wno-foobar, while not actually supporting it. In this dnl case, flag-to-test should be -Wfoobar. If flag-to-use is empty dnl flag-to-test will be used. dnl dnl Depends on the AX_CHECK_COMPILER_FLAGS macro. dnl dnl @category Misc dnl @author Sven Hesse dnl @version 2015-07-12 dnl @license Creative Commons CC0 1.0 Universal Public Domain Dedication AC_DEFUN([AX_CHECK_COMPILER_FLAGS_VAR], [ AC_LANG_PUSH([$1]) FLAG_TO_USE="$4" if test -z "$FLAG_TO_USE"; then FLAG_TO_USE="$3" fi AX_CHECK_COMPILER_FLAGS([$3], [-Werror], AS_VAR_APPEND([$2], [" $FLAG_TO_USE"])) AC_LANG_POP([$1]) ]) xoreos-tools-0.0.5/m4/ax_check_iconv.m4000066400000000000000000000010271331663051500177210ustar00rootroot00000000000000#serial 1000 dnl @synopsis AX_CHECK_ICONV(action-if, action-if-not) dnl dnl @summary check for a useable iconv() function dnl dnl Defines LIBICONV and LTLIBICONV. dnl dnl @category InstalledPackages dnl @author Sven Hesse dnl @version 2013-12-14 dnl @license Creative Commons CC0 1.0 Universal Public Domain Dedication AC_DEFUN([AX_CHECK_ICONV], [ AM_ICONV if test "x$am_cv_func_iconv" != "xyes"; then ifelse([$2], , :, [$2]) else ifelse([$1], , :, [$1]) fi AC_SUBST(LIBICONV) AC_SUBST(LTLIBICONV) ]) xoreos-tools-0.0.5/m4/ax_check_xml2.m4000066400000000000000000000031101331663051500174600ustar00rootroot00000000000000#serial 1000 dnl @synopsis AX_CHECK_XML2(major, minor, patch, action-if, action-if-not) dnl dnl @summary check for libxml2 of sufficient major, minor and patch version dnl dnl Defines XML2_LIBS, XML2_CFLAGS. See xml2-config(1) man page. dnl dnl @category InstalledPackages dnl @author Sven Hesse dnl @version 2015-06-09 dnl @license Creative Commons CC0 1.0 Universal Public Domain Dedication AC_DEFUN([AX_CHECK_XML2], [ AC_ARG_VAR(XML2_CONFIG, [xml2-config utility]) AC_ARG_VAR(XML2_CFLAGS, [C compiler flags for XML2]) AC_ARG_VAR(XML2_LIBS, [libraries to pass to the linker for XML2]) AC_CHECK_PROG([XML2_CONFIG], [xml2-config], [xml2-config]) if test -n "$XML2_CONFIG"; then if test -z "$XML2_CFLAGS"; then XML2_CFLAGS=`$XML2_CONFIG --cflags` fi if test -z "$XML2_LIBS"; then XML2_LIBS=`$XML2_CONFIG --libs` fi fi save_CFLAGS="$CFLAGS" save_CXXFLAGS="$CXXFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $XML2_CFLAGS" CXXFLAGS="$CXXFLAGS $XML2_CFLAGS" CPPFLAGS="$CPPFLAGS $XML2_CFLAGS" LIBS="$LIBS $XML2_LIBS" AC_CHECK_HEADER([libxml/xmlversion.h], AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include int main(int argc, char **argv) { #if LIBXML_VERSION < (($1 * 10000) + ($2 * 100) + $3) #error libxml2 version too low #endif return 0; } ]])], noxml2=0, noxml2=1), noxml2=1) CFLAGS="$save_CFLAGS" CXXFLAGS="$save_CXXFLAGS" CPPFLAGS="$save_CPPFLAGS" LIBS="$save_LIBS" if test "$noxml2" = "1"; then ifelse([$5], , :, [$5]) else ifelse([$4], , :, [$4]) fi AC_SUBST(XML2_CFLAGS) AC_SUBST(XML2_LIBS) ]) xoreos-tools-0.0.5/m4/ax_check_zlib.m4000066400000000000000000000024351331663051500175470ustar00rootroot00000000000000#serial 1000 dnl @synopsis AX_CHECK_ZLIB(major, minor, revision, subrevision, action-if, action-if-not) dnl dnl @summary check for ZLIB of sufficient major, minor, revision and subrevision version dnl dnl Defines ZLIB_LIBS, ZLIB_CFLAGS. dnl dnl @category InstalledPackages dnl @author Sven Hesse dnl @version 2013-12-14 dnl @license Creative Commons CC0 1.0 Universal Public Domain Dedication AC_DEFUN([AX_CHECK_ZLIB], [ AC_ARG_VAR(ZLIB_CFLAGS, [C compiler flags for zlib]) AC_ARG_VAR(ZLIB_LIBS, [libraries to pass to the linker for zlib]) if test -z "$ZLIB_CFLAGS"; then ZLIB_CFLAGS="" fi if test -z "$ZLIB_LIBS"; then ZLIB_LIBS="-lz" fi save_CFLAGS="$CFLAGS" save_CXXFLAGS="$CXXFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $ZLIB_CFLAGS" CXXFLAGS="$CXXFLAGS $ZLIB_CFLAGS" LIBS="$LIBS $ZLIB_LIBS" AC_CHECK_HEADER([zlib.h], AC_LINK_IFELSE([AC_LANG_SOURCE([[ #include int main(int argc, char **argv) { #if ZLIB_VERNUM < (($1 * 4096) + ($2 * 256) + ($3 * 16) + $4) #error zlib version too low #endif return 0; } ]])], nozlib=0, nozlib=1), nozlib=1) CFLAGS="$save_CFLAGS" CXXFLAGS="$save_CXXFLAGS" LIBS="$save_LIBS" if test "$nozlib" = "1"; then ifelse([$6], , :, [$6]) else ifelse([$5], , :, [$5]) fi AC_SUBST(ZLIB_CFLAGS) AC_SUBST(ZLIB_LIBS) ]) xoreos-tools-0.0.5/m4/ax_pthread.m4000066400000000000000000000516741331663051500171120ustar00rootroot00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 1023 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C++]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_CXXFLAGS="$CXXFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" CXXFLAGS="$ax_pthread_save_CXXFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], [ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif ], [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" ;; esac # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) AS_IF([test "x$GCC" = "xyes"], [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) # Are we compiling with Clang? AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif ], [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" ax_pthread_clang_warning=no # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) PTHREAD_CFLAGS="-pthread" PTHREAD_LIBS= ax_pthread_ok=yes # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_CXXFLAGS="$CXXFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" CXXFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CXXFLAGS" ac_link="$ax_pthread_save_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [ac_link="$ax_pthread_2step_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [break]) ]) done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" CXXFLAGS="$ax_pthread_save_CXXFLAGS" AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" ]) case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -mt,pthread) AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) PTHREAD_CFLAGS="-mt" PTHREAD_LIBS="-lpthread" ;; -*) AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_CXXFLAGS="$CXXFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) CFLAGS="$ax_pthread_save_CFLAGS" CXXFLAGS="$ax_pthread_save_CXXFLAGS" LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_CXXFLAGS="$CXXFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_CACHE_CHECK([for joinable pthread attribute], [ax_cv_PTHREAD_JOINABLE_ATTR], [ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $ax_pthread_attr; return attr /* ; */])], [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], []) done ]) AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes"], [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$ax_cv_PTHREAD_JOINABLE_ATTR], [Define to necessary symbol if this constant uses a non-standard name on your system.]) ax_pthread_joinable_attr_defined=yes ]) AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac ]) AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes"], [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) ax_pthread_prio_inherit_defined=yes ]) CFLAGS="$ax_pthread_save_CFLAGS" CXXFLAGS="$ax_pthread_save_CXXFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD xoreos-tools-0.0.5/m4/boost.m4000066400000000000000000001565551331663051500161250ustar00rootroot00000000000000# boost.m4: Locate Boost headers and libraries for autoconf-based projects. # Copyright (C) 2007-2011, 2014 Benoit Sigoure # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Additional permission under section 7 of the GNU General Public # License, version 3 ("GPLv3"): # # If you convey this file as part of a work that contains a # configuration script generated by Autoconf, you may do so under # terms of your choice. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . m4_define([_BOOST_SERIAL], [m4_translit([ # serial 1025 ], [# ], [])]) # Original sources can be found at http://github.com/tsuna/boost.m4 # You can fetch the latest version of the script by doing: # wget http://github.com/tsuna/boost.m4/raw/master/build-aux/boost.m4 # ------ # # README # # ------ # # This file provides several macros to use the various Boost libraries. # The first macro is BOOST_REQUIRE. It will simply check if it's possible to # find the Boost headers of a given (optional) minimum version and it will # define BOOST_CPPFLAGS accordingly. It will add an option --with-boost to # your configure so that users can specify non standard locations. # If the user's environment contains BOOST_ROOT and --with-boost was not # specified, --with-boost=$BOOST_ROOT is implicitly used. # For more README and documentation, go to http://github.com/tsuna/boost.m4 # Note: THESE MACROS ASSUME THAT YOU USE LIBTOOL. If you don't, don't worry, # simply read the README, it will show you what to do step by step. m4_pattern_forbid([^_?(BOOST|Boost)_]) # _BOOST_SED_CPP(SED-PROGRAM, PROGRAM, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # -------------------------------------------------------- # Same as AC_EGREP_CPP, but leave the result in conftest.i. # # SED-PROGRAM is *not* overquoted, as in AC_EGREP_CPP. It is expanded # in double-quotes, so escape your double quotes. # # It could be useful to turn this into a macro which extracts the # value of any macro. m4_define([_BOOST_SED_CPP], [AC_LANG_PUSH([C++])dnl AC_LANG_PREPROC_REQUIRE()dnl AC_REQUIRE([AC_PROG_SED])dnl AC_LANG_CONFTEST([AC_LANG_SOURCE([[$2]])]) AS_IF([dnl eval is necessary to expand ac_cpp. dnl Ultrix and Pyramid sh refuse to redirect output of eval, so use subshell. dnl Beware of Windows end-of-lines, for instance if we are running dnl some Windows programs under Wine. In that case, boost/version.hpp dnl is certainly using "\r\n", but the regular Unix shell will only dnl strip `\n' with backquotes, not the `\r'. This results in dnl boost_cv_lib_version='1_37\r' for instance, which breaks dnl everything else. dnl Cannot use 'dnl' after [$4] because a trailing dnl may break AC_CACHE_CHECK dnl dnl Beware that GCC 5, when expanding macros, may embed # line directives dnl a within single line: dnl dnl # 1 "conftest.cc" dnl # 1 "" dnl # 1 "" dnl # 1 "conftest.cc" dnl # 1 "/opt/local/include/boost/version.hpp" 1 3 dnl # 2 "conftest.cc" 2 dnl boost-lib-version = dnl # 2 "conftest.cc" 3 dnl "1_56" dnl dnl So get rid of the # lines, and glue the remaining ones together. (eval "$ac_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | grep -v '#' | tr -d '\r' | tr -s '\n' ' ' | $SED -n -e "$1" >conftest.i 2>&1], [$3], [$4]) rm -rf conftest* AC_LANG_POP([C++])dnl ])# _BOOST_SED_CPP # BOOST_REQUIRE([VERSION], [ACTION-IF-NOT-FOUND]) # ----------------------------------------------- # Look for Boost. If version is given, it must either be a literal of the form # "X.Y.Z" where X, Y and Z are integers (the ".Z" part being optional) or a # variable "$var". # Defines the value BOOST_CPPFLAGS. This macro only checks for headers with # the required version, it does not check for any of the Boost libraries. # On # success, defines HAVE_BOOST. On failure, calls the optional # ACTION-IF-NOT-FOUND action if one was supplied. # Otherwise aborts with an error message. AC_DEFUN_ONCE([BOOST_REQUIRE], [AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_PROG_GREP])dnl echo "$as_me: this is boost.m4[]_BOOST_SERIAL" >&AS_MESSAGE_LOG_FD boost_save_IFS=$IFS boost_version_req=$1 IFS=. set x $boost_version_req 0 0 0 IFS=$boost_save_IFS shift boost_version_req=`expr "$[1]" '*' 100000 + "$[2]" '*' 100 + "$[3]"` boost_version_req_string=$[1].$[2].$[3] AC_ARG_WITH([boost], [AS_HELP_STRING([--with-boost=DIR], [prefix of Boost $1 @<:@guess@:>@])])dnl AC_ARG_VAR([BOOST_ROOT],[Location of Boost installation])dnl # If BOOST_ROOT is set and the user has not provided a value to # --with-boost, then treat BOOST_ROOT as if it the user supplied it. if test x"$BOOST_ROOT" != x; then if test x"$with_boost" = x; then AC_MSG_NOTICE([Detected BOOST_ROOT; continuing with --with-boost=$BOOST_ROOT]) with_boost=$BOOST_ROOT else AC_MSG_NOTICE([Detected BOOST_ROOT=$BOOST_ROOT, but overridden by --with-boost=$with_boost]) fi fi AC_SUBST([DISTCHECK_CONFIGURE_FLAGS], ["$DISTCHECK_CONFIGURE_FLAGS '--with-boost=$with_boost'"])dnl boost_save_CPPFLAGS=$CPPFLAGS AC_CACHE_CHECK([for Boost headers version >= $boost_version_req_string], [boost_cv_inc_path], [boost_cv_inc_path=no AC_LANG_PUSH([C++])dnl m4_pattern_allow([^BOOST_VERSION$])dnl AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include #if !defined BOOST_VERSION # error BOOST_VERSION is not defined #elif BOOST_VERSION < $boost_version_req # error Boost headers version < $boost_version_req #endif ]])]) # If the user provided a value to --with-boost, use it and only it. case $with_boost in #( ''|yes) set x '' /opt/local/include /usr/local/include /opt/include \ /usr/include C:/Boost/include;; #( *) set x "$with_boost/include" "$with_boost";; esac shift for boost_dir do # Without --layout=system, Boost (or at least some versions) installs # itself in /include/boost-. This inner loop helps to # find headers in such directories. # # Any ${boost_dir}/boost-x_xx directories are searched in reverse version # order followed by ${boost_dir}. The final '.' is a sentinel for # searching $boost_dir" itself. Entries are whitespace separated. # # I didn't indent this loop on purpose (to avoid over-indented code) boost_layout_system_search_list=`cd "$boost_dir" 2>/dev/null \ && ls -1 | "${GREP}" '^boost-' | sort -rn -t- -k2 \ && echo .` for boost_inc in $boost_layout_system_search_list do if test x"$boost_inc" != x.; then boost_inc="$boost_dir/$boost_inc" else boost_inc="$boost_dir" # Uses sentinel in boost_layout_system_search_list fi if test x"$boost_inc" != x; then # We are going to check whether the version of Boost installed # in $boost_inc is usable by running a compilation that # #includes it. But if we pass a -I/some/path in which Boost # is not installed, the compiler will just skip this -I and # use other locations (either from CPPFLAGS, or from its list # of system include directories). As a result we would use # header installed on the machine instead of the /some/path # specified by the user. So in that precise case (trying # $boost_inc), make sure the version.hpp exists. # # Use test -e as there can be symlinks. test -e "$boost_inc/boost/version.hpp" || continue CPPFLAGS="$CPPFLAGS -I$boost_inc" fi AC_COMPILE_IFELSE([], [boost_cv_inc_path=yes], [boost_cv_version=no]) if test x"$boost_cv_inc_path" = xyes; then if test x"$boost_inc" != x; then boost_cv_inc_path=$boost_inc fi break 2 fi done done AC_LANG_POP([C++])dnl ]) case $boost_cv_inc_path in #( no) boost_errmsg="cannot find Boost headers version >= $boost_version_req_string" m4_if([$2], [], [AC_MSG_ERROR([$boost_errmsg])], [AC_MSG_NOTICE([$boost_errmsg])]) $2 ;;#( yes) BOOST_CPPFLAGS= ;;#( *) AC_SUBST([BOOST_CPPFLAGS], ["-I$boost_cv_inc_path"])dnl ;; esac if test x"$boost_cv_inc_path" != xno; then AC_DEFINE([HAVE_BOOST], [1], [Defined if the requested minimum BOOST version is satisfied]) AC_CACHE_CHECK([for Boost's header version], [boost_cv_lib_version], [m4_pattern_allow([^BOOST_LIB_VERSION$])dnl _BOOST_SED_CPP([[/^boost-lib-version = /{s///;s/[\" ]//g;p;q;}]], [#include boost-lib-version = BOOST_LIB_VERSION], [boost_cv_lib_version=`cat conftest.i`])]) # e.g. "134" for 1_34_1 or "135" for 1_35 boost_major_version=`echo "$boost_cv_lib_version" | sed 's/_//;s/_.*//'` case $boost_major_version in #( '' | *[[!0-9]]*) AC_MSG_ERROR([invalid value: boost_major_version='$boost_major_version']) ;; esac fi CPPFLAGS=$boost_save_CPPFLAGS ])# BOOST_REQUIRE # BOOST_STATIC() # -------------- # Add the "--enable-static-boost" configure argument. If this argument is given # on the command line, static versions of the libraries will be looked up. AC_DEFUN([BOOST_STATIC], [AC_ARG_ENABLE([static-boost], [AS_HELP_STRING([--enable-static-boost], [Prefer the static boost libraries over the shared ones [no]])], [enable_static_boost=yes], [enable_static_boost=no])])# BOOST_STATIC # BOOST_FIND_HEADER([HEADER-NAME], [ACTION-IF-NOT-FOUND], [ACTION-IF-FOUND]) # -------------------------------------------------------------------------- # Wrapper around AC_CHECK_HEADER for Boost headers. Useful to check for # some parts of the Boost library which are only made of headers and don't # require linking (such as Boost.Foreach). # # Default ACTION-IF-NOT-FOUND: Fail with a fatal error unless Boost couldn't be # found in the first place, in which case by default a notice is issued to the # user. Presumably if we haven't died already it's because it's OK to not have # Boost, which is why only a notice is issued instead of a hard error. # # Default ACTION-IF-FOUND: define the preprocessor symbol HAVE_ in # case of success # (where HEADER-NAME is written LIKE_THIS, e.g., # HAVE_BOOST_FOREACH_HPP). AC_DEFUN([BOOST_FIND_HEADER], [AC_REQUIRE([BOOST_REQUIRE])dnl if test x"$boost_cv_inc_path" = xno; then m4_default([$2], [AC_MSG_NOTICE([Boost not available, not searching for $1])]) else AC_LANG_PUSH([C++])dnl boost_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_CHECK_HEADER([$1], [m4_default([$3], [AC_DEFINE(AS_TR_CPP([HAVE_$1]), [1], [Define to 1 if you have <$1>])])], [m4_default([$2], [AC_MSG_ERROR([cannot find $1])])]) CPPFLAGS=$boost_save_CPPFLAGS AC_LANG_POP([C++])dnl fi ])# BOOST_FIND_HEADER # BOOST_FIND_LIBS([COMPONENT-NAME], [CANDIDATE-LIB-NAMES], # [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], # [CXX-PROLOGUE]) # -------------------------------------------------------------- # Look for the Boost library COMPONENT-NAME (e.g., `thread', for # libboost_thread) under the possible CANDIDATE-LIB-NAMES (e.g., # "thread_win32 thread"). Check that HEADER-NAME works and check that # libboost_LIB-NAME can link with the code CXX-TEST. The optional # argument CXX-PROLOGUE can be used to include some C++ code before # the `main' function. # # Invokes BOOST_FIND_HEADER([HEADER-NAME]) (see above). # # Boost libraries typically come compiled with several flavors (with different # runtime options) so PREFERRED-RT-OPT is the preferred suffix. A suffix is one # or more of the following letters: sgdpn (in that order). s = static # runtime, d = debug build, g = debug/diagnostic runtime, p = STLPort build, # n = (unsure) STLPort build without iostreams from STLPort (it looks like `n' # must always be used along with `p'). Additionally, PREFERRED-RT-OPT can # start with `mt-' to indicate that there is a preference for multi-thread # builds. Some sample values for PREFERRED-RT-OPT: (nothing), mt, d, mt-d, gdp # ... If you want to make sure you have a specific version of Boost # (eg, >= 1.33) you *must* invoke BOOST_REQUIRE before this macro. AC_DEFUN([BOOST_FIND_LIBS], [AC_REQUIRE([BOOST_REQUIRE])dnl AC_REQUIRE([_BOOST_FIND_COMPILER_TAG])dnl AC_REQUIRE([BOOST_STATIC])dnl AC_REQUIRE([_BOOST_GUESS_WHETHER_TO_USE_MT])dnl if test x"$boost_cv_inc_path" = xno; then AC_MSG_NOTICE([Boost not available, not searching for the Boost $1 library]) else dnl The else branch is huge and wasn't intended on purpose. AC_LANG_PUSH([C++])dnl AS_VAR_PUSHDEF([Boost_lib], [boost_cv_lib_$1])dnl AS_VAR_PUSHDEF([Boost_lib_LDFLAGS], [boost_cv_lib_$1_LDFLAGS])dnl AS_VAR_PUSHDEF([Boost_lib_LDPATH], [boost_cv_lib_$1_LDPATH])dnl AS_VAR_PUSHDEF([Boost_lib_LIBS], [boost_cv_lib_$1_LIBS])dnl BOOST_FIND_HEADER([$4]) boost_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" AC_CACHE_CHECK([for the Boost $1 library], [Boost_lib], [_BOOST_FIND_LIBS($@)]) case $Boost_lib in #( (no) _AC_MSG_LOG_CONFTEST AC_MSG_ERROR([cannot find the flags to link with Boost $1]) ;; esac AC_SUBST(AS_TR_CPP([BOOST_$1_LDFLAGS]), [$Boost_lib_LDFLAGS])dnl AC_SUBST(AS_TR_CPP([BOOST_$1_LDPATH]), [$Boost_lib_LDPATH])dnl AC_SUBST([BOOST_LDPATH], [$Boost_lib_LDPATH])dnl AC_SUBST(AS_TR_CPP([BOOST_$1_LIBS]), [$Boost_lib_LIBS])dnl CPPFLAGS=$boost_save_CPPFLAGS AS_VAR_POPDEF([Boost_lib])dnl AS_VAR_POPDEF([Boost_lib_LDFLAGS])dnl AS_VAR_POPDEF([Boost_lib_LDPATH])dnl AS_VAR_POPDEF([Boost_lib_LIBS])dnl AC_LANG_POP([C++])dnl fi ]) # BOOST_FIND_LIB([LIB-NAME], # [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], # [CXX-PROLOGUE]) # -------------------------------------------------------------- # Backward compatibility wrapper for BOOST_FIND_LIBS. AC_DEFUN([BOOST_FIND_LIB], [BOOST_FIND_LIBS([$1], $@)]) # _BOOST_FIND_LIBS([LIB-NAME], [CANDIDATE-LIB-NAMES], # [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], # [CXX-PROLOGUE]) # -------------------------------------------------------------- # Real implementation of BOOST_FIND_LIBS: rely on these local macros: # Boost_lib, Boost_lib_LDFLAGS, Boost_lib_LDPATH, Boost_lib_LIBS # # The algorithm is as follows: first look for a given library name # according to the user's PREFERRED-RT-OPT. For each library name, we # prefer to use the ones that carry the tag (toolset name). Each # library is searched through the various standard paths were Boost is # usually installed. If we can't find the standard variants, we try # to enforce -mt (for instance on MacOSX, libboost_thread.dylib # doesn't exist but there's -obviously- libboost_thread-mt.dylib). AC_DEFUN([_BOOST_FIND_LIBS], [Boost_lib=no case "$3" in #( (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X$3" : 'Xmt-*\(.*\)'`;; #( (*) boost_mt=; boost_rtopt=$3;; esac if test $enable_static_boost = yes; then boost_rtopt="s$boost_rtopt" fi # Find the proper debug variant depending on what we've been asked to find. case $boost_rtopt in #( (*d*) boost_rt_d=$boost_rtopt;; #( (*[[sgpn]]*) # Insert the `d' at the right place (in between `sg' and `pn') boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( (*) boost_rt_d='-d';; esac # If the PREFERRED-RT-OPT are not empty, prepend a `-'. test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" $boost_guess_use_mt && boost_mt=-mt # Look for the abs path the static archive. # $libext is computed by Libtool but let's make sure it's non empty. test -z "$libext" && AC_MSG_ERROR([the libext variable is empty, did you invoke Libtool?]) boost_save_ac_objext=$ac_objext # Generate the test file. AC_LANG_CONFTEST([AC_LANG_PROGRAM([$6 #include <$4>], [$5])]) dnl Optimization hacks: compiling C++ is slow, especially with Boost. What dnl we're trying to do here is guess the right combination of link flags dnl (LIBS / LDFLAGS) to use a given library. This can take several dnl iterations before it succeeds and is thus *very* slow. So what we do dnl instead is that we compile the code first (and thus get an object file, dnl typically conftest.o). Then we try various combinations of link flags dnl until we succeed to link conftest.o in an executable. The problem is dnl that the various TRY_LINK / COMPILE_IFELSE macros of Autoconf always dnl remove all the temporary files including conftest.o. So the trick here dnl is to temporarily change the value of ac_objext so that conftest.o is dnl preserved accross tests. This is obviously fragile and I will burn in dnl hell for not respecting Autoconf's documented interfaces, but in the dnl mean time, it optimizes the macro by a factor of 5 to 30. dnl Another small optimization: the first argument of AC_COMPILE_IFELSE left dnl empty because the test file is generated only once above (before we dnl start the for loops). AC_COMPILE_IFELSE([], [ac_objext=do_not_rm_me_plz], [AC_MSG_ERROR([cannot compile a test that uses Boost $1])]) ac_objext=$boost_save_ac_objext boost_failed_libs= # Don't bother to ident the following nested for loops, only the 2 # innermost ones matter. for boost_lib_ in $2; do for boost_tag_ in -$boost_cv_lib_tag ''; do for boost_ver_ in -$boost_cv_lib_version ''; do for boost_mt_ in $boost_mt -mt ''; do for boost_rtopt_ in $boost_rtopt '' -d; do for boost_full_suffix in \ $boost_last_suffix \ x$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ x$boost_tag_$boost_rtopt_$boost_ver_ \ x$boost_tag_$boost_mt_$boost_ver_ \ x$boost_tag_$boost_ver_ do boost_real_suffix=`echo "$boost_full_suffix" | sed 's/^x//'` boost_lib="boost_$boost_lib_$boost_real_suffix" # Avoid testing twice the same lib case $boost_failed_libs in #( (*@$boost_lib@*) continue;; esac # If with_boost is empty, we'll search in /lib first, which is not quite # right so instead we'll try to a location based on where the headers are. boost_tmp_lib=$with_boost test x"$with_boost" = x && boost_tmp_lib=${boost_cv_inc_path%/include} for boost_ldpath in "$boost_tmp_lib/lib" '' \ /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ "$with_boost" C:/Boost/lib /lib* do # Don't waste time with directories that don't exist. if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then continue fi boost_save_LDFLAGS=$LDFLAGS # Are we looking for a static library? case $boost_ldpath:$boost_rtopt_ in #( (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) Boost_lib_LIBS="$boost_ldpath/lib$boost_lib.$libext" test -e "$Boost_lib_LIBS" || continue;; #( (*) # No: use -lboost_foo to find the shared library. Boost_lib_LIBS="-l$boost_lib";; esac boost_save_LIBS=$LIBS LIBS="$Boost_lib_LIBS $LIBS" test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" dnl First argument of AC_LINK_IFELSE left empty because the test file is dnl generated only once above (before we start the for loops). _BOOST_AC_LINK_IFELSE([], [Boost_lib=yes], [Boost_lib=no]) ac_objext=$boost_save_ac_objext LDFLAGS=$boost_save_LDFLAGS LIBS=$boost_save_LIBS if test x"$Boost_lib" = xyes; then # Check or used cached result of whether or not using -R or # -rpath makes sense. Some implementations of ld, such as for # Mac OSX, require -rpath but -R is the flag known to work on # other systems. https://github.com/tsuna/boost.m4/issues/19 AC_CACHE_VAL([boost_cv_rpath_link_ldflag], [case $boost_ldpath in '') # Nothing to do. boost_cv_rpath_link_ldflag= boost_rpath_link_ldflag_found=yes;; *) for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" LIBS="$boost_save_LIBS $Boost_lib_LIBS" _BOOST_AC_LINK_IFELSE([], [boost_rpath_link_ldflag_found=yes break], [boost_rpath_link_ldflag_found=no]) done ;; esac AS_IF([test "x$boost_rpath_link_ldflag_found" != "xyes"], [AC_MSG_ERROR([Unable to determine whether to use -R or -rpath])]) LDFLAGS=$boost_save_LDFLAGS LIBS=$boost_save_LIBS ]) test x"$boost_ldpath" != x && Boost_lib_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" Boost_lib_LDPATH="$boost_ldpath" boost_last_suffix="$boost_full_suffix" break 7 else boost_failed_libs="$boost_failed_libs@$boost_lib@" fi done done done done done done done # boost_lib_ rm -f conftest.$ac_objext ]) # --------------------------------------- # # Checks for the various Boost libraries. # # --------------------------------------- # # List of boost libraries: http://www.boost.org/libs/libraries.htm # The page http://beta.boost.org/doc/libs is useful: it gives the first release # version of each library (among other things). # BOOST_DEFUN(LIBRARY, CODE) # -------------------------- # Define BOOST_ as a macro that runs CODE. # # Use indir to avoid the warning on underquoted macro name given to AC_DEFUN. m4_define([BOOST_DEFUN], [m4_indir([AC_DEFUN], m4_toupper([BOOST_$1]), [m4_pushdef([BOOST_Library], [$1])dnl $2 m4_popdef([BOOST_Library])dnl ]) ]) # BOOST_ARRAY() # ------------- # Look for Boost.Array BOOST_DEFUN([Array], [BOOST_FIND_HEADER([boost/array.hpp])]) # BOOST_ASIO() # ------------ # Look for Boost.Asio (new in Boost 1.35). BOOST_DEFUN([Asio], [AC_REQUIRE([BOOST_SYSTEM])dnl BOOST_FIND_HEADER([boost/asio.hpp])]) # BOOST_ATOMIC([PREFERRED-RT-OPT]) # ------------------------------- # Look for Boost.Atomic. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Atomic], [BOOST_FIND_LIB([atomic], [$1], [boost/atomic.hpp], [boost::atomic a;], [#ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDINT_H #include #endif]) ])# BOOST_ATOMIC # BOOST_BIND() # ------------ # Look for Boost.Bind. BOOST_DEFUN([Bind], [BOOST_FIND_HEADER([boost/bind.hpp])]) # BOOST_CHRONO() # -------------- # Look for Boost.Chrono. BOOST_DEFUN([Chrono], [# Do we have to check for Boost.System? This link-time dependency was # added as of 1.35.0. If we have a version <1.35, we must not attempt to # find Boost.System as it didn't exist by then. if test $boost_major_version -ge 135; then BOOST_SYSTEM([$1]) fi # end of the Boost.System check. boost_filesystem_save_LIBS=$LIBS boost_filesystem_save_LDFLAGS=$LDFLAGS m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" BOOST_FIND_LIB([chrono], [$1], [boost/chrono.hpp], [boost::chrono::thread_clock d;]) if test $enable_static_boost = yes && test $boost_major_version -ge 135; then BOOST_CHRONO_LIBS="$BOOST_CHRONO_LIBS $BOOST_SYSTEM_LIBS" fi LIBS=$boost_filesystem_save_LIBS LDFLAGS=$boost_filesystem_save_LDFLAGS ])# BOOST_CHRONO # BOOST_CONTEXT([PREFERRED-RT-OPT]) # ----------------------------------- # Look for Boost.Context. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. # # * This library was introduced in Boost 1.51.0 # * The signatures of make_fcontext() and jump_fcontext were changed in 1.56.0 # * A dependency on boost_thread appears in 1.57.0 BOOST_DEFUN([Context], [boost_context_save_LIBS=$LIBS boost_context_save_LDFLAGS=$LDFLAGS if test $boost_major_version -ge 157; then BOOST_THREAD([$1]) m4_pattern_allow([^BOOST_THREAD_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_THREAD_LIBS" LDFLAGS="$LDFLAGS $BOOST_THREAD_LDFLAGS" fi BOOST_FIND_LIB([context], [$1], [boost/context/all.hpp],[[ // creates a stack void * stack_pointer = new void*[4096]; std::size_t const size = sizeof(void*[4096]); #if BOOST_VERSION <= 105100 ctx::make_fcontext(&fc, f); return ctx::jump_fcontext(&fcm, &fc, 3) == 6; #else fc = ctx::make_fcontext(stack_pointer, size, f); return ctx::jump_fcontext(&fcm, fc, 3) == 6; #endif ]],[dnl #include #if BOOST_VERSION <= 105100 namespace ctx = boost::ctx; static ctx::fcontext_t fcm, fc; static void f(intptr_t i) { ctx::jump_fcontext(&fc, &fcm, i * 2); } #elif BOOST_VERSION <= 105500 namespace ctx = boost::context; // context static ctx::fcontext_t fcm, *fc; // context-function static void f(intptr_t i) { ctx::jump_fcontext(fc, &fcm, i * 2); } #else namespace ctx = boost::context; // context static ctx::fcontext_t fcm, fc; // context-function static void f(intptr_t i) { ctx::jump_fcontext(&fc, fcm, i * 2); } #endif ]) LIBS=$boost_context_save_LIBS LDFLAGS=$boost_context_save_LDFLAGS ])# BOOST_CONTEXT # BOOST_CONVERSION() # ------------------ # Look for Boost.Conversion (cast / lexical_cast) BOOST_DEFUN([Conversion], [BOOST_FIND_HEADER([boost/cast.hpp]) BOOST_FIND_HEADER([boost/lexical_cast.hpp]) ])# BOOST_CONVERSION # BOOST_COROUTINE([PREFERRED-RT-OPT]) # ----------------------------------- # Look for Boost.Coroutine. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. This library was introduced in Boost # 1.53.0 BOOST_DEFUN([Coroutine], [ boost_coroutine_save_LIBS=$LIBS boost_coroutine_save_LDFLAGS=$LDFLAGS # Link-time dependency from coroutine to context BOOST_CONTEXT([$1]) # Starting from Boost 1.55 a dependency on Boost.System is added if test $boost_major_version -ge 155; then BOOST_SYSTEM([$1]) fi m4_pattern_allow([^BOOST_(CONTEXT|SYSTEM)_(LIBS|LDFLAGS)]) LIBS="$LIBS $BOOST_CONTEXT_LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_CONTEXT_LDFLAGS" # in 1.53 coroutine was a header only library if test $boost_major_version -eq 153; then BOOST_FIND_HEADER([boost/coroutine/coroutine.hpp]) else BOOST_FIND_LIB([coroutine], [$1], [boost/coroutine/coroutine.hpp], [ #include #if BOOST_VERSION <= 105500 boost::coroutines::coroutine coro; coro.get(); #else boost::coroutines::asymmetric_coroutine::pull_type coro; coro.get(); #endif ]) fi # Link-time dependency from coroutine to context, existed only in 1.53, in 1.54 # coroutine doesn't use context from its headers but from its library. if test $boost_major_version -eq 153 || test $enable_static_boost = yes && test $boost_major_version -ge 154; then BOOST_COROUTINE_LIBS="$BOOST_COROUTINE_LIBS $BOOST_CONTEXT_LIBS" BOOST_COROUTINE_LDFLAGS="$BOOST_COROUTINE_LDFLAGS $BOOST_CONTEXT_LDFLAGS" fi if test $enable_static_boost = yes && test $boost_major_version -ge 155; then BOOST_COROUTINE_LIBS="$BOOST_COROUTINE_LIBS $BOOST_SYSTEM_LIBS" BOOST_COROUTINE_LDFLAGS="$BOOST_COROUTINE_LDFLAGS $BOOST_SYSTEM_LDFLAGS" fi LIBS=$boost_coroutine_save_LIBS LDFLAGS=$boost_coroutine_save_LDFLAGS ])# BOOST_COROUTINE # BOOST_CRC() # ----------- # Look for Boost.CRC BOOST_DEFUN([CRC], [BOOST_FIND_HEADER([boost/crc.hpp]) ])# BOOST_CRC # BOOST_DATE_TIME([PREFERRED-RT-OPT]) # ----------------------------------- # Look for Boost.Date_Time. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Date_Time], [BOOST_FIND_LIB([date_time], [$1], [boost/date_time/posix_time/posix_time.hpp], [boost::posix_time::ptime t;]) ])# BOOST_DATE_TIME # BOOST_FILESYSTEM([PREFERRED-RT-OPT]) # ------------------------------------ # Look for Boost.Filesystem. For the documentation of PREFERRED-RT-OPT, see # the documentation of BOOST_FIND_LIB above. # Do not check for boost/filesystem.hpp because this file was introduced in # 1.34. BOOST_DEFUN([Filesystem], [# Do we have to check for Boost.System? This link-time dependency was # added as of 1.35.0. If we have a version <1.35, we must not attempt to # find Boost.System as it didn't exist by then. if test $boost_major_version -ge 135; then BOOST_SYSTEM([$1]) fi # end of the Boost.System check. boost_filesystem_save_LIBS=$LIBS boost_filesystem_save_LDFLAGS=$LDFLAGS m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" BOOST_FIND_LIB([filesystem], [$1], [boost/filesystem/path.hpp], [boost::filesystem::path p;]) if test $enable_static_boost = yes && test $boost_major_version -ge 135; then BOOST_FILESYSTEM_LIBS="$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS" fi LIBS=$boost_filesystem_save_LIBS LDFLAGS=$boost_filesystem_save_LDFLAGS ])# BOOST_FILESYSTEM # BOOST_FLYWEIGHT() # ----------------- # Look for Boost.Flyweight. BOOST_DEFUN([Flyweight], [dnl There's a hidden dependency on pthreads. AC_REQUIRE([_BOOST_PTHREAD_FLAG])dnl BOOST_FIND_HEADER([boost/flyweight.hpp]) AC_SUBST([BOOST_FLYWEIGHT_LIBS], [$boost_cv_pthread_flag]) ]) # BOOST_FOREACH() # --------------- # Look for Boost.Foreach. BOOST_DEFUN([Foreach], [BOOST_FIND_HEADER([boost/foreach.hpp])]) # BOOST_FORMAT() # -------------- # Look for Boost.Format. # Note: we can't check for boost/format/format_fwd.hpp because the header isn't # standalone. It can't be compiled because it triggers the following error: # boost/format/detail/config_macros.hpp:88: error: 'locale' in namespace 'std' # does not name a type BOOST_DEFUN([Format], [BOOST_FIND_HEADER([boost/format.hpp])]) # BOOST_FUNCTION() # ---------------- # Look for Boost.Function BOOST_DEFUN([Function], [BOOST_FIND_HEADER([boost/function.hpp])]) # BOOST_GEOMETRY() # ---------------- # Look for Boost.Geometry (new since 1.47.0). BOOST_DEFUN([Geometry], [BOOST_FIND_HEADER([boost/geometry.hpp]) ])# BOOST_GEOMETRY # BOOST_GRAPH([PREFERRED-RT-OPT]) # ------------------------------- # Look for Boost.Graphs. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Graph], [boost_graph_save_LIBS=$LIBS boost_graph_save_LDFLAGS=$LDFLAGS # Link-time dependency from graph to regex was added as of 1.40.0. if test $boost_major_version -ge 140; then BOOST_REGEX([$1]) m4_pattern_allow([^BOOST_REGEX_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_REGEX_LIBS" LDFLAGS="$LDFLAGS $BOOST_REGEX_LDFLAGS" fi BOOST_FIND_LIB([graph], [$1], [boost/graph/adjacency_list.hpp], [boost::adjacency_list<> g;]) LIBS=$boost_graph_save_LIBS LDFLAGS=$boost_graph_save_LDFLAGS ])# BOOST_GRAPH # BOOST_IOSTREAMS([PREFERRED-RT-OPT]) # ----------------------------------- # Look for Boost.IOStreams. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([IOStreams], [BOOST_FIND_LIB([iostreams], [$1], [boost/iostreams/device/file_descriptor.hpp], [boost::iostreams::file_descriptor fd; fd.close();]) ])# BOOST_IOSTREAMS # BOOST_HASH() # ------------ # Look for Boost.Functional/Hash BOOST_DEFUN([Hash], [BOOST_FIND_HEADER([boost/functional/hash.hpp])]) # BOOST_LAMBDA() # -------------- # Look for Boost.Lambda BOOST_DEFUN([Lambda], [BOOST_FIND_HEADER([boost/lambda/lambda.hpp])]) # BOOST_LOCALE() # -------------- # Look for Boost.Locale BOOST_DEFUN([Locale], [ boost_locale_save_LIBS=$LIBS boost_locale_save_LDFLAGS=$LDFLAGS # require SYSTEM for boost-1.50.0 and up if test $boost_major_version -ge 150; then BOOST_SYSTEM([$1]) m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" fi # end of the Boost.System check. BOOST_FIND_LIB([locale], [$1], [boost/locale.hpp], [[boost::locale::generator gen; std::locale::global(gen(""));]]) LIBS=$boost_locale_save_LIBS LDFLAGS=$boost_locale_save_LDFLAGS ])# BOOST_LOCALE # BOOST_LOG([PREFERRED-RT-OPT]) # ----------------------------- # Look for Boost.Log. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Log], [boost_log_save_LIBS=$LIBS boost_log_save_LDFLAGS=$LDFLAGS BOOST_SYSTEM([$1]) BOOST_FILESYSTEM([$1]) BOOST_DATE_TIME([$1]) m4_pattern_allow([^BOOST_(SYSTEM|FILESYSTEM|DATE_TIME)_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_DATE_TIME_LIBS $BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS" LDFLAGS="$LDFLAGS $BOOST_DATE_TIME_LDFLAGS $BOOST_FILESYSTEM_LDFLAGS $BOOST_SYSTEM_LDFLAGS" BOOST_FIND_LIB([log], [$1], [boost/log/core/core.hpp], [boost::log::attribute a; a.get_value();]) LIBS=$boost_log_save_LIBS LDFLAGS=$boost_log_save_LDFLAGS ])# BOOST_LOG # BOOST_LOG_SETUP([PREFERRED-RT-OPT]) # ----------------------------------- # Look for Boost.Log. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Log_Setup], [boost_log_setup_save_LIBS=$LIBS boost_log_setup_save_LDFLAGS=$LDFLAGS BOOST_LOG([$1]) m4_pattern_allow([^BOOST_LOG_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_LOG_LIBS" LDFLAGS="$LDFLAGS $BOOST_LOG_LDFLAGS" BOOST_FIND_LIB([log_setup], [$1], [boost/log/utility/setup/from_settings.hpp], [boost::log::basic_settings bs; bs.empty();]) LIBS=$boost_log_setup_save_LIBS LDFLAGS=$boost_log_setup_save_LDFLAGS ])# BOOST_LOG_SETUP # BOOST_MATH() # ------------ # Look for Boost.Math # TODO: This library isn't header-only but it comes in multiple different # flavors that don't play well with BOOST_FIND_LIB (e.g, libboost_math_c99, # libboost_math_c99f, libboost_math_c99l, libboost_math_tr1, # libboost_math_tr1f, libboost_math_tr1l). This macro must be fixed to do the # right thing anyway. BOOST_DEFUN([Math], [BOOST_FIND_HEADER([boost/math/special_functions.hpp])]) # BOOST_MPI([PREFERRED-RT-OPT]) # ------------------------------- # Look for Boost MPI. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. Uses MPICXX variable if it is # set, otherwise tries CXX # BOOST_DEFUN([MPI], [boost_save_CXX=${CXX} boost_save_CXXCPP=${CXXCPP} if test x"${MPICXX}" != x; then CXX=${MPICXX} CXXCPP="${MPICXX} -E" fi BOOST_FIND_LIB([mpi], [$1], [boost/mpi.hpp], [int argc = 0; char **argv = 0; boost::mpi::environment env(argc,argv);]) CXX=${boost_save_CXX} CXXCPP=${boost_save_CXXCPP} ])# BOOST_MPI # BOOST_MULTIARRAY() # ------------------ # Look for Boost.MultiArray BOOST_DEFUN([MultiArray], [BOOST_FIND_HEADER([boost/multi_array.hpp])]) # BOOST_NUMERIC_UBLAS() # -------------------------- # Look for Boost.NumericUblas (Basic Linear Algebra) BOOST_DEFUN([Numeric_Ublas], [BOOST_FIND_HEADER([boost/numeric/ublas/vector.hpp]) ])# BOOST_NUMERIC_UBLAS # BOOST_NUMERIC_CONVERSION() # -------------------------- # Look for Boost.NumericConversion (policy-based numeric conversion) BOOST_DEFUN([Numeric_Conversion], [BOOST_FIND_HEADER([boost/numeric/conversion/converter.hpp]) ])# BOOST_NUMERIC_CONVERSION # BOOST_OPTIONAL() # ---------------- # Look for Boost.Optional BOOST_DEFUN([Optional], [BOOST_FIND_HEADER([boost/optional.hpp])]) # BOOST_PREPROCESSOR() # -------------------- # Look for Boost.Preprocessor BOOST_DEFUN([Preprocessor], [BOOST_FIND_HEADER([boost/preprocessor/repeat.hpp])]) # BOOST_RANGE() # -------------------- # Look for Boost.Range BOOST_DEFUN([Range], [BOOST_FIND_HEADER([boost/range/adaptors.hpp])]) # BOOST_UNORDERED() # ----------------- # Look for Boost.Unordered BOOST_DEFUN([Unordered], [BOOST_FIND_HEADER([boost/unordered_map.hpp])]) # BOOST_UUID() # ------------ # Look for Boost.Uuid BOOST_DEFUN([Uuid], [BOOST_FIND_HEADER([boost/uuid/uuid.hpp])]) # BOOST_PROGRAM_OPTIONS([PREFERRED-RT-OPT]) # ----------------------------------------- # Look for Boost.Program_options. For the documentation of PREFERRED-RT-OPT, # see the documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Program_Options], [BOOST_FIND_LIB([program_options], [$1], [boost/program_options.hpp], [boost::program_options::options_description d("test");]) ])# BOOST_PROGRAM_OPTIONS # _BOOST_PYTHON_CONFIG(VARIABLE, FLAG) # ------------------------------------ # Save VARIABLE, and define it via `python-config --FLAG`. # Substitute BOOST_PYTHON_VARIABLE. m4_define([_BOOST_PYTHON_CONFIG], [AC_SUBST([BOOST_PYTHON_$1], [`python-config --$2 2>/dev/null`])dnl boost_python_save_$1=$$1 $1="$$1 $BOOST_PYTHON_$1"]) # BOOST_PYTHON([PREFERRED-RT-OPT]) # -------------------------------- # Look for Boost.Python. For the documentation of PREFERRED-RT-OPT, # see the documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Python], [_BOOST_PYTHON_CONFIG([CPPFLAGS], [includes]) _BOOST_PYTHON_CONFIG([LDFLAGS], [ldflags]) _BOOST_PYTHON_CONFIG([LIBS], [libs]) m4_pattern_allow([^BOOST_PYTHON_MODULE$])dnl BOOST_FIND_LIBS([python], [python python3], [$1], [boost/python.hpp], [], [BOOST_PYTHON_MODULE(empty) {}]) CPPFLAGS=$boost_python_save_CPPFLAGS LDFLAGS=$boost_python_save_LDFLAGS LIBS=$boost_python_save_LIBS ])# BOOST_PYTHON # BOOST_REF() # ----------- # Look for Boost.Ref BOOST_DEFUN([Ref], [BOOST_FIND_HEADER([boost/ref.hpp])]) # BOOST_REGEX([PREFERRED-RT-OPT]) # ------------------------------- # Look for Boost.Regex. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Regex], [BOOST_FIND_LIB([regex], [$1], [boost/regex.hpp], [boost::regex exp("*"); boost::regex_match("foo", exp);]) ])# BOOST_REGEX # BOOST_SCOPE_EXIT() # ------------ # Look for Boost.ScopeExit. BOOST_DEFUN([SCOPE_EXIT], [BOOST_FIND_HEADER([boost/scope_exit.hpp])]) # BOOST_SERIALIZATION([PREFERRED-RT-OPT]) # --------------------------------------- # Look for Boost.Serialization. For the documentation of PREFERRED-RT-OPT, see # the documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Serialization], [BOOST_FIND_LIB([serialization], [$1], [boost/archive/text_oarchive.hpp], [std::ostream* o = 0; // Cheap way to get an ostream... boost::archive::text_oarchive t(*o);]) ])# BOOST_SERIALIZATION # BOOST_SIGNALS([PREFERRED-RT-OPT]) # --------------------------------- # Look for Boost.Signals. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Signals], [BOOST_FIND_LIB([signals], [$1], [boost/signal.hpp], [boost::signal s;]) ])# BOOST_SIGNALS # BOOST_SIGNALS2() # ---------------- # Look for Boost.Signals2 (new since 1.39.0). BOOST_DEFUN([Signals2], [BOOST_FIND_HEADER([boost/signals2.hpp]) ])# BOOST_SIGNALS2 # BOOST_SMART_PTR() # ----------------- # Look for Boost.SmartPtr BOOST_DEFUN([Smart_Ptr], [BOOST_FIND_HEADER([boost/scoped_ptr.hpp]) BOOST_FIND_HEADER([boost/shared_ptr.hpp]) ]) # BOOST_STATICASSERT() # -------------------- # Look for Boost.StaticAssert BOOST_DEFUN([StaticAssert], [BOOST_FIND_HEADER([boost/static_assert.hpp])]) # BOOST_STRING_ALGO() # ------------------- # Look for Boost.StringAlgo BOOST_DEFUN([String_Algo], [BOOST_FIND_HEADER([boost/algorithm/string.hpp]) ]) # BOOST_SYSTEM([PREFERRED-RT-OPT]) # -------------------------------- # Look for Boost.System. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. This library was introduced in Boost # 1.35.0. BOOST_DEFUN([System], [BOOST_FIND_LIB([system], [$1], [boost/system/error_code.hpp], [boost::system::error_code e; e.clear();]) ])# BOOST_SYSTEM # BOOST_TEST([PREFERRED-RT-OPT]) # ------------------------------ # Look for Boost.Test. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Test], [m4_pattern_allow([^BOOST_CHECK$])dnl BOOST_FIND_LIB([unit_test_framework], [$1], [boost/test/unit_test.hpp], [BOOST_CHECK(2 == 2);], [using boost::unit_test::test_suite; test_suite* init_unit_test_suite(int argc, char ** argv) { return NULL; }]) ])# BOOST_TEST # BOOST_THREAD([PREFERRED-RT-OPT]) # --------------------------------- # Look for Boost.Thread. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Thread], [dnl Having the pthread flag is required at least on GCC3 where dnl boost/thread.hpp would complain if we try to compile without dnl -pthread on GNU/Linux. AC_REQUIRE([_BOOST_PTHREAD_FLAG])dnl boost_thread_save_LIBS=$LIBS boost_thread_save_LDFLAGS=$LDFLAGS boost_thread_save_CPPFLAGS=$CPPFLAGS # Link-time dependency from thread to system was added as of 1.49.0. if test $boost_major_version -ge 149; then BOOST_SYSTEM([$1]) fi # end of the Boost.System check. m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" CPPFLAGS="$CPPFLAGS $boost_cv_pthread_flag" # When compiling for the Windows platform, the threads library is named # differently. This suffix doesn't exist in new versions of Boost, or # possibly new versions of GCC on mingw I am assuming it's Boost's change for # now and I am setting version to 1.48, for lack of knowledge as to when this # change occurred. if test $boost_major_version -lt 148; then case $host_os in (*mingw*) boost_thread_lib_ext=_win32;; esac fi BOOST_FIND_LIBS([thread], [thread$boost_thread_lib_ext], [$1], [boost/thread.hpp], [boost::thread t; boost::mutex m;]) case $host_os in (*mingw*) boost_thread_w32_socket_link=-lws2_32;; esac BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag $boost_thread_w32_socket_link" BOOST_THREAD_LDFLAGS="$BOOST_SYSTEM_LDFLAGS" BOOST_CPPFLAGS="$BOOST_CPPFLAGS $boost_cv_pthread_flag" LIBS=$boost_thread_save_LIBS LDFLAGS=$boost_thread_save_LDFLAGS CPPFLAGS=$boost_thread_save_CPPFLAGS ])# BOOST_THREAD AU_ALIAS([BOOST_THREADS], [BOOST_THREAD]) # BOOST_TOKENIZER() # ----------------- # Look for Boost.Tokenizer BOOST_DEFUN([Tokenizer], [BOOST_FIND_HEADER([boost/tokenizer.hpp])]) # BOOST_TRIBOOL() # --------------- # Look for Boost.Tribool BOOST_DEFUN([Tribool], [BOOST_FIND_HEADER([boost/logic/tribool_fwd.hpp]) BOOST_FIND_HEADER([boost/logic/tribool.hpp]) ]) # BOOST_TUPLE() # ------------- # Look for Boost.Tuple BOOST_DEFUN([Tuple], [BOOST_FIND_HEADER([boost/tuple/tuple.hpp])]) # BOOST_TYPETRAITS() # -------------------- # Look for Boost.TypeTraits BOOST_DEFUN([TypeTraits], [BOOST_FIND_HEADER([boost/type_traits.hpp])]) # BOOST_UTILITY() # --------------- # Look for Boost.Utility (noncopyable, result_of, base-from-member idiom, # etc.) BOOST_DEFUN([Utility], [BOOST_FIND_HEADER([boost/utility.hpp])]) # BOOST_VARIANT() # --------------- # Look for Boost.Variant. BOOST_DEFUN([Variant], [BOOST_FIND_HEADER([boost/variant/variant_fwd.hpp]) BOOST_FIND_HEADER([boost/variant.hpp])]) # BOOST_POINTER_CONTAINER() # ------------------------ # Look for Boost.PointerContainer BOOST_DEFUN([Pointer_Container], [BOOST_FIND_HEADER([boost/ptr_container/ptr_deque.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_list.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_vector.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_array.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_set.hpp]) BOOST_FIND_HEADER([boost/ptr_container/ptr_map.hpp]) ])# BOOST_POINTER_CONTAINER # BOOST_WAVE([PREFERRED-RT-OPT]) # ------------------------------ # NOTE: If you intend to use Wave/Spirit with thread support, make sure you # call BOOST_THREAD first. # Look for Boost.Wave. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. BOOST_DEFUN([Wave], [AC_REQUIRE([BOOST_FILESYSTEM])dnl AC_REQUIRE([BOOST_DATE_TIME])dnl boost_wave_save_LIBS=$LIBS boost_wave_save_LDFLAGS=$LDFLAGS m4_pattern_allow([^BOOST_((FILE)?SYSTEM|DATE_TIME|THREAD)_(LIBS|LDFLAGS)$])dnl LIBS="$LIBS $BOOST_SYSTEM_LIBS $BOOST_FILESYSTEM_LIBS $BOOST_DATE_TIME_LIBS \ $BOOST_THREAD_LIBS" LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS $BOOST_FILESYSTEM_LDFLAGS \ $BOOST_DATE_TIME_LDFLAGS $BOOST_THREAD_LDFLAGS" BOOST_FIND_LIB([wave], [$1], [boost/wave.hpp], [boost::wave::token_id id; get_token_name(id);]) LIBS=$boost_wave_save_LIBS LDFLAGS=$boost_wave_save_LDFLAGS ])# BOOST_WAVE # BOOST_XPRESSIVE() # ----------------- # Look for Boost.Xpressive (new since 1.36.0). BOOST_DEFUN([Xpressive], [BOOST_FIND_HEADER([boost/xpressive/xpressive.hpp])]) # ----------------- # # Internal helpers. # # ----------------- # # _BOOST_PTHREAD_FLAG() # --------------------- # Internal helper for BOOST_THREAD. Computes boost_cv_pthread_flag # which must be used in CPPFLAGS and LIBS. # # Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3, # boost/thread.hpp will trigger a #error if -pthread isn't used: # boost/config/requires_threads.hpp:47:5: #error "Compiler threading support # is not turned on. Please set the correct command line options for # threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" # # Based on ACX_PTHREAD: http://autoconf-archive.cryp.to/acx_pthread.html AC_DEFUN([_BOOST_PTHREAD_FLAG], [AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_LANG_PUSH([C++])dnl AC_CACHE_CHECK([for the flags needed to use pthreads], [boost_cv_pthread_flag], [ boost_cv_pthread_flag= # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # (none): in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -lpthreads: AIX (must check this before -lpthread) # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads) # -pthreads: Solaris/GCC # -mthreads: MinGW32/GCC, Lynx/GCC # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # -lpthread: GNU Linux, etc. # --thread-safe: KAI C++ case $host_os in #( *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: boost_pthread_flags="-pthreads -lpthread -mt -pthread";; #( *) boost_pthread_flags="-lpthreads -Kthread -kthread -llthread -pthread \ -pthreads -mthreads -lpthread --thread-safe -mt";; esac # Generate the test file. AC_LANG_CONFTEST([AC_LANG_PROGRAM([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0);])]) for boost_pthread_flag in '' $boost_pthread_flags; do boost_pthread_ok=false dnl Re-use the test file already generated. boost_pthreads__save_LIBS=$LIBS LIBS="$LIBS $boost_pthread_flag" AC_LINK_IFELSE([], [if grep ".*$boost_pthread_flag" conftest.err; then echo "This flag seems to have triggered warnings" >&AS_MESSAGE_LOG_FD else boost_pthread_ok=:; boost_cv_pthread_flag=$boost_pthread_flag fi]) LIBS=$boost_pthreads__save_LIBS $boost_pthread_ok && break done ]) AC_LANG_POP([C++])dnl ])# _BOOST_PTHREAD_FLAG # _BOOST_gcc_test(MAJOR, MINOR) # ----------------------------- # Internal helper for _BOOST_FIND_COMPILER_TAG. m4_define([_BOOST_gcc_test], ["defined __GNUC__ && __GNUC__ == $1 && __GNUC_MINOR__ == $2 && !defined __ICC \ && (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw$1$2" \ "defined __GNUC__ && __GNUC__ == $1 && __GNUC_MINOR__ == $2 && !defined __ICC @ gcc$1$2"])dnl # _BOOST_clang_test(MAJOR, MINOR) # ----------------------------- # Internal helper for _BOOST_FIND_COMPILER_TAG. m4_define([_BOOST_clang_test], ["defined __clang__ && __clang_major__ == $1 && __clang_minor__ == $2 @ clang$1$2"])dnl # _BOOST_FIND_COMPILER_TAG() # -------------------------- # Internal. When Boost is installed without --layout=system, each library # filename will hold a suffix that encodes the compiler used during the # build. The Boost build system seems to call this a `tag'. AC_DEFUN([_BOOST_FIND_COMPILER_TAG], [AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([for the toolset name used by Boost for $CXX], [boost_cv_lib_tag], [boost_cv_lib_tag=unknown if test x$boost_cv_inc_path != xno; then AC_LANG_PUSH([C++])dnl # The following tests are mostly inspired by boost/config/auto_link.hpp # The list is sorted to most recent/common to oldest compiler (in order # to increase the likelihood of finding the right compiler with the # least number of compilation attempt). # Beware that some tests are sensible to the order (for instance, we must # look for MinGW before looking for GCC3). # I used one compilation test per compiler with a #error to recognize # each compiler so that it works even when cross-compiling (let me know # if you know a better approach). # Known missing tags (known from Boost's tools/build/v2/tools/common.jam): # como, edg, kcc, bck, mp, sw, tru, xlc # I'm not sure about my test for `il' (be careful: Intel's ICC pre-defines # the same defines as GCC's). for i in \ _BOOST_clang_test(6, 0) \ _BOOST_clang_test(5, 0) \ _BOOST_clang_test(4, 0) \ _BOOST_clang_test(3, 9) \ _BOOST_clang_test(3, 8) \ _BOOST_clang_test(3, 7) \ _BOOST_clang_test(3, 6) \ _BOOST_clang_test(3, 5) \ _BOOST_clang_test(3, 4) \ _BOOST_clang_test(3, 3) \ _BOOST_clang_test(3, 2) \ _BOOST_clang_test(3, 1) \ _BOOST_clang_test(3, 0) \ _BOOST_gcc_test(8, 1) \ _BOOST_gcc_test(8, 0) \ _BOOST_gcc_test(7, 3) \ _BOOST_gcc_test(7, 2) \ _BOOST_gcc_test(7, 1) \ _BOOST_gcc_test(7, 0) \ _BOOST_gcc_test(6, 4) \ _BOOST_gcc_test(6, 3) \ _BOOST_gcc_test(6, 2) \ _BOOST_gcc_test(6, 1) \ _BOOST_gcc_test(6, 0) \ _BOOST_gcc_test(5, 5) \ _BOOST_gcc_test(5, 4) \ _BOOST_gcc_test(5, 3) \ _BOOST_gcc_test(5, 2) \ _BOOST_gcc_test(5, 1) \ _BOOST_gcc_test(5, 0) \ _BOOST_gcc_test(4, 10) \ _BOOST_gcc_test(4, 9) \ _BOOST_gcc_test(4, 8) \ _BOOST_gcc_test(4, 7) \ _BOOST_gcc_test(4, 6) \ _BOOST_gcc_test(4, 5) \ _BOOST_gcc_test(4, 4) \ _BOOST_gcc_test(4, 3) \ _BOOST_gcc_test(4, 2) \ _BOOST_gcc_test(4, 1) \ _BOOST_gcc_test(4, 0) \ "defined __GNUC__ && __GNUC__ == 3 && !defined __ICC \ && (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw" \ _BOOST_gcc_test(3, 4) \ _BOOST_gcc_test(3, 3) \ "defined _MSC_VER && _MSC_VER >= 1500 @ vc90" \ "defined _MSC_VER && _MSC_VER == 1400 @ vc80" \ _BOOST_gcc_test(3, 2) \ "defined _MSC_VER && _MSC_VER == 1310 @ vc71" \ _BOOST_gcc_test(3, 1) \ _BOOST_gcc_test(3, 0) \ "defined __BORLANDC__ @ bcb" \ "defined __ICC && (defined __unix || defined __unix__) @ il" \ "defined __ICL @ iw" \ "defined _MSC_VER && _MSC_VER == 1300 @ vc7" \ _BOOST_gcc_test(2, 95) \ "defined __MWERKS__ && __MWERKS__ <= 0x32FF @ cw9" \ "defined _MSC_VER && _MSC_VER < 1300 && !defined UNDER_CE @ vc6" \ "defined _MSC_VER && _MSC_VER < 1300 && defined UNDER_CE @ evc4" \ "defined __MWERKS__ && __MWERKS__ <= 0x31FF @ cw8" do boost_tag_test=`expr "X$i" : 'X\([[^@]]*\) @ '` boost_tag=`expr "X$i" : 'X[[^@]]* @ \(.*\)'` AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if $boost_tag_test /* OK */ #else # error $boost_tag_test #endif ]])], [boost_cv_lib_tag=$boost_tag; break], []) done AC_LANG_POP([C++])dnl case $boost_cv_lib_tag in #( # Some newer (>= 1.35?) versions of Boost seem to only use "gcc" as opposed # to "gcc41" for instance. *-gcc | *'-gcc ') :;; #( Don't re-add -gcc: it's already in there. gcc*) boost_tag_x= case $host_os in #( darwin*) if test $boost_major_version -ge 136; then # The `x' added in r46793 of Boost. boost_tag_x=x fi;; esac # We can specify multiple tags in this variable because it's used by # BOOST_FIND_LIB that does a `for tag in -$boost_cv_lib_tag' ... boost_cv_lib_tag="$boost_tag_x$boost_cv_lib_tag -${boost_tag_x}gcc" ;; #( unknown) AC_MSG_WARN([[could not figure out which toolset name to use for $CXX]]) boost_cv_lib_tag= ;; esac fi])dnl end of AC_CACHE_CHECK ])# _BOOST_FIND_COMPILER_TAG # _BOOST_GUESS_WHETHER_TO_USE_MT() # -------------------------------- # Compile a small test to try to guess whether we should favor MT (Multi # Thread) flavors of Boost. Sets boost_guess_use_mt accordingly. AC_DEFUN([_BOOST_GUESS_WHETHER_TO_USE_MT], [# Check whether we do better use `mt' even though we weren't ask to. AC_LANG_PUSH([C++])dnl AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if defined _REENTRANT || defined _MT || defined __MT__ /* use -mt */ #else # error MT not needed #endif ]])], [boost_guess_use_mt=:], [boost_guess_use_mt=false]) AC_LANG_POP([C++])dnl ]) # _BOOST_AC_LINK_IFELSE(PROGRAM, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # ------------------------------------------------------------------- # Fork of _AC_LINK_IFELSE that preserves conftest.o across calls. Fragile, # will break when Autoconf changes its internals. Requires that you manually # rm -f conftest.$ac_objext in between to really different tests, otherwise # you will try to link a conftest.o left behind by a previous test. # Used to aggressively optimize BOOST_FIND_LIB (see the big comment in this # macro). # # Don't use "break" in the actions, as it would short-circuit some code # this macro runs after the actions. m4_define([_BOOST_AC_LINK_IFELSE], [m4_ifvaln([$1], [AC_LANG_CONFTEST([$1])])dnl rm -f conftest$ac_exeext boost_save_ac_ext=$ac_ext boost_use_source=: # If we already have a .o, re-use it. We change $ac_ext so that $ac_link # tries to link the existing object file instead of compiling from source. test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false && _AS_ECHO_LOG([re-using the existing conftest.$ac_objext]) AS_IF([_AC_DO_STDERR($ac_link) && { test -z "$ac_[]_AC_LANG_ABBREV[]_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_executable_p conftest$ac_exeext dnl FIXME: use AS_TEST_X instead when 2.61 is widespread enough. }], [$2], [if $boost_use_source; then _AC_MSG_LOG_CONFTEST fi $3]) ac_objext=$boost_save_ac_objext ac_ext=$boost_save_ac_ext dnl Delete also the IPA/IPO (Inter Procedural Analysis/Optimization) dnl information created by the PGI compiler (conftest_ipa8_conftest.oo), dnl as it would interfere with the next link command. rm -f core conftest.err conftest_ipa8_conftest.oo \ conftest$ac_exeext m4_ifval([$1], [conftest.$ac_ext])[]dnl ])# _BOOST_AC_LINK_IFELSE # Local Variables: # mode: autoconf # End: xoreos-tools-0.0.5/m4/iconv.m4000066400000000000000000000220661331663051500161020ustar00rootroot00000000000000# iconv.m4 serial 1019 (gettext-0.18.2) dnl Copyright (C) 2000-2002, 2007-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_LIB_LINKFLAGS_BODY([iconv]) ]) AC_DEFUN([AM_ICONV_LINK], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) dnl Add $INCICONV to CPPFLAGS before performing the following checks, dnl because if the user has installed libiconv and not disabled its use dnl via --without-libiconv-prefix, he wants to use it. The first dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. am_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #include ]], [[iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);]])], [am_cv_func_iconv=yes]) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #include ]], [[iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);]])], [am_cv_lib_iconv=yes] [am_cv_func_iconv=yes]) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, dnl Solaris 10. am_save_LIBS="$LIBS" if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" fi am_cv_func_iconv_works=no for ac_iconv_const in '' 'const'; do AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include #include #ifndef ICONV_CONST # define ICONV_CONST $ac_iconv_const #endif ]], [[int result = 0; /* Test against AIX 5.1 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); if (cd_utf8_to_88591 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ char buf[10]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_utf8_to_88591, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 1; iconv_close (cd_utf8_to_88591); } } /* Test against Solaris 10 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); if (cd_ascii_to_88591 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\263"; char buf[10]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_ascii_to_88591, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 2; iconv_close (cd_ascii_to_88591); } } /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ { iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\304"; static char buf[2] = { (char)0xDE, (char)0xAD }; ICONV_CONST char *inptr = input; size_t inbytesleft = 1; char *outptr = buf; size_t outbytesleft = 1; size_t res = iconv (cd_88591_to_utf8, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) result |= 4; iconv_close (cd_88591_to_utf8); } } #if 0 /* This bug could be worked around by the caller. */ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ { iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; char buf[50]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_88591_to_utf8, &inptr, &inbytesleft, &outptr, &outbytesleft); if ((int)res > 0) result |= 8; iconv_close (cd_88591_to_utf8); } } #endif /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is provided. */ if (/* Try standardized names. */ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) /* Try IRIX, OSF/1 names. */ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) /* Try AIX names. */ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) /* Try HP-UX names. */ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) result |= 16; return result; ]])], [am_cv_func_iconv_works=yes], , [case "$host_os" in aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; *) am_cv_func_iconv_works="guessing yes" ;; esac]) test "$am_cv_func_iconv_works" = no || break done LIBS="$am_save_LIBS" ]) case "$am_cv_func_iconv_works" in *no) am_func_iconv=no am_cv_lib_iconv=no ;; *) am_func_iconv=yes ;; esac else am_func_iconv=no am_cv_lib_iconv=no fi if test "$am_func_iconv" = yes; then AC_DEFINE([HAVE_ICONV], [1], [Define if you have the iconv() function and it works.]) fi if test "$am_cv_lib_iconv" = yes; then AC_MSG_CHECKING([how to link with libiconv]) AC_MSG_RESULT([$LIBICONV]) else dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV dnl either. CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi AC_SUBST([LIBICONV]) AC_SUBST([LTLIBICONV]) ]) dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to dnl avoid warnings like dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". dnl This is tricky because of the way 'aclocal' is implemented: dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. dnl Otherwise aclocal's initial scan pass would miss the macro definition. dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. dnl Otherwise aclocal would emit many "Use of uninitialized value $1" dnl warnings. m4_define([gl_iconv_AC_DEFUN], m4_version_prereq([2.64], [[AC_DEFUN_ONCE( [$1], [$2])]], [m4_ifdef([gl_00GNULIB], [[AC_DEFUN_ONCE( [$1], [$2])]], [[AC_DEFUN( [$1], [$2])]])])) gl_iconv_AC_DEFUN([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL([am_cv_proto_iconv], [ AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ]], [[]])], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"]) am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([ $am_cv_proto_iconv]) AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], [Define as const if the declaration of iconv() needs const.]) dnl Also substitute ICONV_CONST in the gnulib generated . m4_ifdef([gl_ICONV_H_DEFAULTS], [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) if test -n "$am_cv_proto_iconv_arg1"; then ICONV_CONST="const" fi ]) fi ]) xoreos-tools-0.0.5/m4/lib-ld.m4000066400000000000000000000071461331663051500161310ustar00rootroot00000000000000# lib-ld.m4 serial 1006 dnl Copyright (C) 1996-2003, 2009-2015 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Subroutines of libtool.m4, dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid dnl collision with libtool.m4. dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. AC_DEFUN([AC_LIB_PROG_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], [# I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 /dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL([acl_cv_path_LD], [if test -z "$LD"; then acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$acl_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 = 1.10 to complain if config.rpath is missing. m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done ]) wl="$acl_cv_wl" acl_libext="$acl_cv_libext" acl_shlibext="$acl_cv_shlibext" acl_libname_spec="$acl_cv_libname_spec" acl_library_names_spec="$acl_cv_library_names_spec" acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" acl_hardcode_direct="$acl_cv_hardcode_direct" acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" dnl Determine whether the user wants rpath handling at all. AC_ARG_ENABLE([rpath], [ --disable-rpath do not hardcode runtime library paths], :, enable_rpath=yes) ]) dnl AC_LIB_FROMPACKAGE(name, package) dnl declares that libname comes from the given package. The configure file dnl will then not have a --with-libname-prefix option but a dnl --with-package-prefix option. Several libraries can come from the same dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar dnl macro call that searches for libname. AC_DEFUN([AC_LIB_FROMPACKAGE], [ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) define([acl_frompackage_]NAME, [$2]) popdef([NAME]) pushdef([PACK],[$2]) pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) define([acl_libsinpackage_]PACKUP, m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) popdef([PACKUP]) popdef([PACK]) ]) dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. AC_DEFUN([AC_LIB_LINKFLAGS_BODY], [ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) dnl Autoconf >= 2.61 supports dots in --with options. pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_ARG_WITH(P_A_C_K[-prefix], [[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" if test "$acl_libdirstem2" != "$acl_libdirstem" \ && ! test -d "$withval/$acl_libdirstem"; then additional_libdir="$withval/$acl_libdirstem2" fi fi fi ]) dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= LTLIB[]NAME= INC[]NAME= LIB[]NAME[]_PREFIX= dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been dnl computed. So it has to be reset here. HAVE_LIB[]NAME= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='$1 $2' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" dnl See if it was already located by an earlier AC_LIB_LINKFLAGS dnl or AC_LIB_HAVE_LINKFLAGS call. uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" else dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined dnl that this library doesn't exist. So just drop it. : fi else dnl Search the library lib$name in $additional_libdir and $LDFLAGS dnl and the already constructed $LIBNAME/$LTLIBNAME. found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" dnl The same code as in the loop below: dnl First look for a shared library. if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi dnl Then look for a static library. if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` dnl First look for a shared library. if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi dnl Then look for a static library. if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then dnl Found the library. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then dnl Linking with a shared library. We attempt to hardcode its dnl directory into the executable's runpath, unless it's the dnl standard /usr/lib. if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl Use an explicit option to hardcode DIR into the resulting dnl binary. dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi dnl The hardcoding into $LIBNAME is system dependent. if test "$acl_hardcode_direct" = yes; then dnl Using DIR/libNAME.so during linking hardcodes DIR into the dnl resulting binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then dnl Use an explicit option to hardcode DIR into the resulting dnl binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else dnl Rely on "-L$found_dir". dnl But don't add it if it's already contained in the LDFLAGS dnl or the already constructed $LIBNAME haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH dnl here, because this doesn't fit in flags passed to the dnl compiler. So give up. No hardcoding. This affects only dnl very old systems. dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then dnl Linking with a static library. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" else dnl We shouldn't come here, but anyway it's good to have a dnl fallback. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" fi fi dnl Assume the include files are nearby. additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` if test "$name" = '$1'; then LIB[]NAME[]_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; */$acl_libdirstem2 | */$acl_libdirstem2/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` if test "$name" = '$1'; then LIB[]NAME[]_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's /usr/local/include and we are using GCC on Linux, dnl 3. if it's already present in $CPPFLAGS or the already dnl constructed $INCNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INC[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $INCNAME. INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" fi fi fi fi fi dnl Look for dependencies. if test -n "$found_la"; then dnl Read the .la file. It defines the variables dnl dlname, library_names, old_library, dependency_libs, current, dnl age, revision, installed, dlopen, dlpreopen, libdir. save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" dnl We use only dependency_libs. for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LIBNAME. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LTLIBNAME. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) dnl Handle this in the next round. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) dnl Handle this in the next round. Throw away the .la's dnl directory; it is already contained in a preceding -L dnl option. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) dnl Most likely an immediate library name. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ;; esac done fi else dnl Didn't find the library; assume it is in the system directories dnl known to the linker and runtime loader. (All the system dnl directories known to the linker should also be known to the dnl runtime loader, otherwise the system is severely misconfigured.) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user must dnl pass all path elements in one option. We can arrange that for a dnl single library, but not when more than one $LIBNAMEs are used. alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" else dnl The -rpath options are cumulative. for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then dnl When using libtool, the option that works for both libraries and dnl executables is -R. The -R options are cumulative. for found_dir in $ltrpathdirs; do LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi popdef([P_A_C_K]) popdef([PACKLIBS]) popdef([PACKUP]) popdef([PACK]) popdef([NAME]) ]) dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, dnl unless already present in VAR. dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes dnl contains two or three consecutive elements that belong together. AC_DEFUN([AC_LIB_APPENDTOVAR], [ for element in [$2]; do haveit= for x in $[$1]; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then [$1]="${[$1]}${[$1]:+ }$element" fi done ]) dnl For those cases where a variable contains several -L and -l options dnl referring to unknown libraries and directories, this macro determines the dnl necessary additional linker options for the runtime path. dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) dnl sets LDADDVAR to linker options needed together with LIBSVALUE. dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, dnl otherwise linking without libtool is assumed. AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], [ AC_REQUIRE([AC_LIB_RPATH]) AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) $1= if test "$enable_rpath" != no; then if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then dnl Use an explicit option to hardcode directories into the resulting dnl binary. rpathdirs= next= for opt in $2; do if test -n "$next"; then dir="$next" dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem" \ && test "X$dir" != "X/usr/$acl_libdirstem2"; then rpathdirs="$rpathdirs $dir" fi next= else case $opt in -L) next=yes ;; -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem" \ && test "X$dir" != "X/usr/$acl_libdirstem2"; then rpathdirs="$rpathdirs $dir" fi next= ;; *) next= ;; esac fi done if test "X$rpathdirs" != "X"; then if test -n ""$3""; then dnl libtool is used for linking. Use -R options. for dir in $rpathdirs; do $1="${$1}${$1:+ }-R$dir" done else dnl The linker is used for linking directly. if test -n "$acl_hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user dnl must pass all path elements in one option. alldirs= for dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" $1="$flag" else dnl The -rpath options are cumulative. for dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" $1="${$1}${$1:+ }$flag" done fi fi fi fi fi AC_SUBST([$1]) ]) xoreos-tools-0.0.5/m4/lib-prefix.m4000066400000000000000000000204251331663051500170220ustar00rootroot00000000000000# lib-prefix.m4 serial 1007 (gettext-0.18) dnl Copyright (C) 2001-2005, 2008-2015 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't dnl require excessive bracketing. ifdef([AC_HELP_STRING], [AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], [AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed dnl with the same --prefix option. dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate dnl libraries, but is otherwise very convenient. AC_DEFUN([AC_LIB_PREFIX], [ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib-prefix], [ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib --without-lib-prefix don't search for libraries in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi ]) if test $use_additional = yes; then dnl Potentially add $additional_includedir to $CPPFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's already present in $CPPFLAGS, dnl 3. if it's /usr/local/include and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= for x in $CPPFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $CPPFLAGS. CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" fi fi fi fi dnl Potentially add $additional_libdir to $LDFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's already present in $LDFLAGS, dnl 3. if it's /usr/local/lib and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= for x in $LDFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LDFLAGS. LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" fi fi fi fi fi ]) dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, dnl acl_final_exec_prefix, containing the values to which $prefix and dnl $exec_prefix will expand at the end of the configure script. AC_DEFUN([AC_LIB_PREPARE_PREFIX], [ dnl Unfortunately, prefix and exec_prefix get only finally determined dnl at the end of configure. if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" ]) dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the dnl variables prefix and exec_prefix bound to the values they will have dnl at the end of the configure script. AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], [ acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" $1 exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" ]) dnl AC_LIB_PREPARE_MULTILIB creates dnl - a variable acl_libdirstem, containing the basename of the libdir, either dnl "lib" or "lib64" or "lib/64", dnl - a variable acl_libdirstem2, as a secondary possible value for dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or dnl "lib/amd64". AC_DEFUN([AC_LIB_PREPARE_MULTILIB], [ dnl There is no formal standard regarding lib and lib64. dnl On glibc systems, the current practice is that on a system supporting dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine dnl the compiler's default mode by looking at the compiler's library search dnl path. If at least one of its elements ends in /lib64 or points to a dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. dnl Otherwise we use the default, namely "lib". dnl On Solaris systems, the current practice is that on a system supporting dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. AC_REQUIRE([AC_CANONICAL_HOST]) acl_libdirstem=lib acl_libdirstem2= case "$host_os" in solaris*) dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment dnl . dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the dnl symlink is missing, so we set acl_libdirstem2 too. AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], [AC_EGREP_CPP([sixtyfour bits], [ #ifdef _LP64 sixtyfour bits #endif ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) ]) if test $gl_cv_solaris_64bit = yes; then acl_libdirstem=lib/64 case "$host_cpu" in sparc*) acl_libdirstem2=lib/sparcv9 ;; i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; esac fi ;; *) searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test -n "$searchpath"; then acl_save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; */../ | */.. ) # Better ignore directories of this form. They are misleading. ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) acl_libdirstem=lib64 ;; esac ;; esac fi done IFS="$acl_save_IFS" fi ;; esac test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" ]) xoreos-tools-0.0.5/man/000077500000000000000000000000001331663051500147475ustar00rootroot00000000000000xoreos-tools-0.0.5/man/cbgt2tga.1000066400000000000000000000041511331663051500165270ustar00rootroot00000000000000.Dd July 23, 2015 .Dt CBGT2TGA 1 .Os .Sh NAME .Nm cbgt2tga .Nd CBGT image to TGA converter .Sh SYNOPSIS .Nm cbgt2tga .Op Ar options .Ar cbgt pal 2da tga .Sh DESCRIPTION .Nm converts CBGT image files into common TGA images. CBGT, Compressed BackGround Tiles, are used as area background images in BioWare's Nintendo DS game .Em Sonic Chronicles: The Dark Brotherhood . .Pp Internally, a CBGT consists of a collection of 64\(mu64 pixel cells, divided into tiles of 8\(mu8 pixels. Each cell is compressed using Nintendo's 0x10 LZSS algorithm. Moreover, PAL files with the same name as the CBGT file contain the palette data, and 2DA files with the same name yet again contain the mapping of palette indices onto cells. .Pp The width and height of the final image is not stored within the CBGT file, but the palette mapping 2DA does contain the number cells in X and Y direction, since it stores the palette indices in a two-dimensional array of those dimensions. Therefore, multiplying the number of columns and rows in said 2DA by 64 yields the width and height, respectively, of the final image. .Sh OPTIONS .Bl -tag -width xx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .El .Bl -tag -width xx -compact .It Ar cbgt The name of the CBGT file to read. The CBGT contains the pixel graphics part of the image. .It Ar pal The name of the PAL file to use. The PAL file contains the palette part of the image. .It Ar 2da The name of the 2DA file to use. The 2DA file contains information on which palette to use for each part of the CBGT, and on how many parts are in the CBGT in the first place. .It Ar tga The resulting TGA file will be written there. .El .Sh EXAMPLE Convert a CBGT+PAL+2DA into a TGA: .Pp .Dl $ cbgt2tga a.cbgt a.pal a.2da result.tga .Sh "SEE ALSO" .Xr cdpth2tga 1 , .Xr ncgr2tga 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/cdpth2tga.1000066400000000000000000000036521331663051500167170ustar00rootroot00000000000000.Dd July 23, 2015 .Dt CDPTH2TGA 1 .Os .Sh NAME .Nm cdpth2tga .Nd CDPTH depth image to TGA converter .Sh SYNOPSIS .Nm cdpth2tga .Op Ar options .Ar cdpth 2da tga .Sh DESCRIPTION .Nm converts CDPTH depth information files into common TGA images. CDPTH, Compressed DePTH, are used as depth information for area background images in BioWare's Nintendo DS game .Em Sonic Chronicles: The Dark Brotherhood . .Pp Layout-wise, a CDPTH is stored similar to CBGT: cells of 64\(mu64 pixels, compressed using Nintendo's 0x10 LZSS algorithm. Unlike CBGT, though, the cells themselves are .Em not swizzled into 8\(mu8 tiles, and the pixel value in CDPTH is a 16bit integer specifying a depth. .Pp The width and height of the final image is not stored within the CDPTH file, and has to be provided from the outside, like from the dimensions of the CBGT image, the dimensions of the 2DA file for the CBGT image. .Pp The depth information is stored as 16-bit values, but only the lower 15 bits are used. For conversion into a grayscale image, those 15 bits of grayscale information are further compressed to 8-bit. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .El .Bl -tag -width xx -compact .It Ar cdpth The name of the CDPTH file to read. The CDPTH contains the depth information part of the image. .It Ar 2da The name of the 2DA file to use. The 2DA is necessary to know how many cells are in the CDPTH file. .It Ar tga The resulting TGA file will be written there. .El .Sh EXAMPLE Convert a CDPTH+2DA into a TGA: .Pp .Dl $ cdpth2tga a.cdpth a.2da result.tga .Sh SEE ALSO .Xr cbgt2tga 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/convert2da.1000066400000000000000000000051001331663051500170740ustar00rootroot00000000000000.Dd July 23, 2015 .Dt CONVERT2DA 1 .Os .Sh NAME .Nm convert2da .Nd BioWare 2DA/GDA to 2DA/CSV converter .Sh SYNOPSIS .Nm convert2da .Op Ar options .Ar .Sh DESCRIPTION .Nm converts BioWare's 2DA and GDA files into (cleanly formatted) ASCII 2DA or CSV files. 2DA files are two-dimensional arrays, or tables, holding various information and used throughout many of the BioWare games. They can come in two flavors: binary and plain-text ASCII. GDA files are conceptually the same, but they store their data inside a GFF, a binary hierarchical format. Unlike 2DA files, a GDA does not store its column header name directory. Instead, only a CRC hash of the name encoded in little-endian UTF-16 is stored. .Pp This tool can read all of those formats and produces an easily readable, cleanly formatted ASCII 2DA. Alternatively, it can create a CSV file for further processing. It also contains a lookup table to convert GDA column header hashes back to readable names. Not all column header names are known, though. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl o Ar file .It Fl Fl output Ar file Write the output to this file. If this option is not used, the output is written to .Dv stdout . .It Fl a .It Fl Fl 2da Convert the 2DA or GDA file into an ASCII 2DA file. This is the default mode of operation. .It Fl b .It Fl Fl 2dab Convert the 2DA or GDA file into a binary 2DA file. .It Fl c .It Fl Fl csv Convert the 2DA or GDA file into an CSV file. .El .Bl -tag -width xx -compact .It Ar file The name of the 2DA or GDA file to read. .Pp If more than one input file is given, they must all be GDA files and use the same column layout. They will be pasted together and converted as one GDA. This mimics how the M2DA (multiple 2DA/GDA) work in the .Em Dragon Age games. .El .Sh EXAMPLES Convert the 2DA file1.2da into an ASCII 2DA .Pa file2.2da : .Pp .Dl $ convert2da -a file1.2da -o file2.2da .Pp Convert the 2DA file1.2da into an ASCII 2DA on .Dv stdout : .Pp .Dl $ convert2da -a file1.2da .Pp Convert the 2DA .Pa file1.2da into a binary 2DA .Pa file2.2da : .Pp .Dl $ convert2da -b file1.2da -o file2.2da .Pp Convert the 2DA .Pa file1.2da into a CSV file: .Pp .Dl $ convert2da -c file1.2da -o file2.csv .Sh SEE ALSO .Xr gff2xml 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/desmall.1000066400000000000000000000020651331663051500164550ustar00rootroot00000000000000.Dd July 23, 2015 .Dt DESMALL 1 .Os .Sh NAME .Nm desmall .Nd Nintendo DS LZSS (types 0x00 and 0x10) decompressor .Sh SYNOPSIS .Nm desmall .Op Ar options .Ar input_file output_file .Sh DESCRIPTION .Nm decompresses the SMALL files found in BioWare's Nintendo DS game .Em Sonic Chronicles: The Dark Brotherhood . Only the types 0x00 (uncompressed) and 0x10 (Nintendo DS LZSS 0x10) are supported. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .El .Bl -tag -width Ds -compact .It Ar input_file The SMALL file to decompress. .It Ar output_file The decompressed data is written to this file. .El .Sh EXAMPLE Decompress the file .Pa a.cbgt.small : .Pp .Dl $ desmall a.cbgt.small a.cbgt .Sh SEE ALSO More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/erf.1000066400000000000000000000040731331663051500156110ustar00rootroot00000000000000.Dd June 27, 2018 .Dt ERF 1 .Os .Sh NAME .Nm erf .Nd BioWare ERF (.erf, .mod, .nwm, .sav) archive packer .Sh SYNOPSIS .Nm erf .Op Ar options .Ar output_archive .Op Ar .Sh DESCRIPTION .Nm packs files together into a BioWare ERF archive, found in many BioWare Games as files with the extension .erf, .mod, .nwm or .sav. Moreover, in some games, a .rim file might be an ERF instead of a RIM. .Pp There's several different versions of ERFs. This tool supports only version V1.0, as used by .Em Neverwinter Nights , .Em Knights of the Old Republic , .Em Knights of the Old Republic II , .Em Jade Empire and .Em The Witcher . .Pp Unsupported Features: .Bl -bullet -compact .It Generation of archives with stripped filenames. .It Generation of zlib-compressed archives. .It Generation of Blowfish-encrypted archives. .It Generation of XOR-encrypted archives. .It Setting of a description for archives. .It Usage of paths in archives. .El .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl erf Set archive ID to ERF. .It Fl Fl mod Set archive ID to MOD. .It Fl Fl hak Set archive ID to HAK. .It Fl Fl sav Set archive ID to SAV. .It Fl Fl jade Unalias file types according to .Em Jade Empire rules. .Pp .Em Jade Empire reuses a few file extension IDs differently than other BioWare games. To correctly write Jade Empire ERF archives, use this flag. .It Ar output_archive The ERF archive to be written. .It Ar files One or more files to pack together. .El .Sh EXAMPLES Pack some files together into an ERF archive: .Pp .Dl $ erf archive.erf file1.dat file2.dat file3.dat .Pp Pack some files together into a SAV archive: .Pp .Dl $ erf --sav archive.sav file1.dat file2.dat file3.dat .Sh SEE ALSO .Xr unerf 1 , .Xr unherf 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/fixpremiumgff.1000066400000000000000000000034651331663051500177110ustar00rootroot00000000000000.Dd November 14, 2015 .Dt FIXPREMIUMGFF 1 .Os .Sh NAME .Nm fixpremiumgff .Nd repair BioWare GFF files from encrypted NWN premium module HAKs .Sh SYNOPSIS .Nm fixpremiumgff .Op Ar options .Ar input_file output_file .Sh DESCRIPTION In addition to being encrypted, the main HAK (ERF archive) of .Em Neverwinter Nights premium modules also contains GFF files that have been deliberately broken. .Nm repairs those GFF files, turning them back into standard BioWare GFF files that can be read and manipulated by the usual GFF tools. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl id Ar id Write the string .Ar id into the ID fields of the repaired GFF. By default, the ID is auto-detected from the file name of the broken file. For example, a broken .Pa module.ifo will by default turned into a standard GFF with an ID of .Dq IFO , while an .Pa aribeth.dlg will get the .Dq DLG ID. .El .Bl -tag -width xxxx -compact .It Ar input_file The GFF file to repair. .It Ar output_file The repaired GFF file be be written there. This can be the same as the input file, to repair a broken GFF file in-place. .El .Sh EXAMPLES Repair the file .Pa module.ifo : .Pp .Dl $ fixpremiumgff module.ifo module_fixed.ifo .Pp Repair the file .Pa module.ifo , but overwrite the ID: .Pp .Dl $ fixpremiumgff --id DLG module.ifo module_fixed.ifo .Pp Repair the file .Pa module.ifo in-place: .Pp .Dl $ fixpremiumgff module.ifo module.ifo .Sh SEE ALSO .Xr gff2xml 1 , .Xr unerf 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/gff2xml.1000066400000000000000000000121561331663051500164030ustar00rootroot00000000000000.Dd September 1, 2016 .Dt GFF2XML 1 .Os .Sh NAME .Nm gff2xml .Nd BioWare GFF to XML converter .Sh SYNOPSIS .Nm gff2xml .Op Ar options .Ar input_file .Op Ar output_file .Sh DESCRIPTION .Nm converts BioWare's GFF files (versions V3.2/V3.3 and V4.0/V4.1) into human-readable XML. GFF are hierarchical data files, similar to XML in concept, but stored in binary. As such, these files are used as a basis for many of the file formats found in the BioWare games. For example, an UTC file is a GFF holding a template for a creature, while a GUI file is a GFF describing an in-game menu. .Pp Both version 3 of the format (V3.2/V3.3) and version 4 (V4.0/V4.1) are supported. While they are similar, the 4th version carries several changes to make the files more efficient to read in-game. This includes replacing the string field names (which map to XML tags) with numerical identifiers, resulting in converted XML files that are stripped of their meaning. To compensate, this tool adds readable aliases to many of these numerical identifiers, giving them back their meaning. Unfortunately, not all of them are known. Most notably, the identifiers introduced in .Em Sonic Chronicles: The Dark Brotherhood and .Em Dragon Age 2 are still missing. .Pp The changes in the minor versions (V3.2 vs. V3.3 and V4.0 vs. V4.1) are less significant. V3.3 simply changes which languages are supported, and V4.1 adds a common string table at the start of the file. Both of these additions are handled transparently. .Pp LocStrings found in GFF V3.2 and V3.3 contain localized string data, which, depending on the game and the language, can be encoded in various ways. There is no way to autodetect the specific encoding. .Nm employs a simple heuristic to combat this, but it may fail for certain strings and files. However, there are options to explicitly specify the game this GFF file is from. .Nm will then use the correct game-specific encoding tables. .Pp Unfortunately, even these tables might not be completely correct in all cases. .Em Neverwinter Nights , for example, treated many strings as being encoded in the native encoding used for the language of the game installation. This lead to many people putting non-English strings into fields tagged as language ID 0, nominally reserved for English. To read these files correctly, .Nm provides an --encoding parameter to override the encoding used for a specific language ID. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl cp1252 Read GFF4 strings as Windows CP-1252. Usually, strings in version 4 of the GFF format are encoded in little-endian UTF-16. But some files store them as Windows CP-1252 instead. Since there's no clean way to autodetect the different encoding, this switch manually selects Windows CP-1252. This option only concerns strings embedded in GFF4 files, not GFF3 LocStrings. .It Fl Fl nwnpremium The GFF files found in the encrypted HAK files of .Em Neverwinter Nights premium modules are deliberately broken. This options tells .Nm to work around the brokenness. .It Fl Fl nwn Read LocStrings in an encoding appropriate for .Em Neverwinter Nights . .It Fl Fl nwn2 Read LocStrings in an encoding appropriate for .Em Neverwinter Nights 2 . .It Fl Fl kotor Read LocStrings in an encoding appropriate for .Em Knights of the Old Republic . .It Fl Fl kotor2 Read LocStrings in an encoding appropriate for .Em Knights of the Old Republic II . .It Fl Fl jade Read LocStrings in an encoding appropriate for .Em Jade Empire . .It Fl Fl witcher Read LocStrings in an encoding appropriate for .Em The Witcher . .It Fl Fl dragonage Read LocStrings in an encoding appropriate for .Em Dragon Age: Origins . .It Fl Fl dragonage2 Read LocStrings in an encoding appropriate for .Em Dragon Age II . .It Fl Fl encoding Ar str Override an encoding. The string has to be of the form n=encoding, for example 0=cp-1252 to override the encoding of the (ungendered) language ID 0 to be Windows codepage 1252. To override several encodings, specify the --encoding parameter multiple times. .El .Bl -tag -width xxxx -compact .It Ar input_file The GFF file to convert. .It Op Ar output_file The XML file will be written there. If no output file is specified, the XML data is written to .Dv stdout . The encoding of the XML stream is always UTF-8. .El .Sh EXAMPLES Convert the GFF .Pa file1.utc into an XML file: .Pp .Dl $ gff2xml file1.utc file2.xml .Pp Convert the GFF .Pa file1.utc into an XML file on .Dv stdout : .Pp .Dl $ gff2xml file1.utc .Pp Convert the GFF .Pa file1.utc , which uses Windows CP-1252 strings: .Pp .Dl $ gff2xml --cp1252 file1.utc file2.xml .Pp Convert the GFF .Pa file1.utc , which encodes language ID 0 in LocStrings as Windows CP-1250: .Dl $ gff2xml --encoding 0=cp1250 file1.utc file2.xml .Sh SEE ALSO .Xr convert2da 1 , .Xr fixpremiumgff 1 , .Xr tlk2xml 1 , .Xr ssf2xml 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/nbfs2tga.1000066400000000000000000000032701331663051500165410ustar00rootroot00000000000000.Dd July 23, 2015 .Dt NBFS2TGA 1 .Os .Sh NAME .Nm nbfs2tga .Nd Nintendo raw NBFS image to TGA converter .Sh SYNOPSIS .Nm nbfs2tga .Op Ar options .Ar nbfs nbfp tga .Op Ar width Op Ar height .Sh DESCRIPTION .Nm converts Nintendo's raw NBFS images into common TGA images. Both an NBFS file, containing the pixel data, and an NBFP file with the palette data are needed. If no height is specified, it is calculated using the width value and the size of the NBFS file. If no width is specified either, this tool tries to guess the dimensions. It might guess the wrong dimensions. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .El .Bl -tag -width xx -compact .It Ar nbfs The name of the NBFS file to read. The NBFS contains the pixel graphics part of the image. .It Ar nbfp The name of the NBFP file to use. The NBFP file contains the palette part of the image. .It Ar tga The resulting TGA file will be written there. .It Ar width The width of the NBFS image. .It Ar height The height of the NBFS image. .El .Sh EXAMPLES Convert an NBFS+NBFP into a TGA and specify dimensions: .Pp .Dl $ nbfs2tga a.nbfs a.nbfp a.tga 64 64 .Pp Convert an NBFS+NBFP into a TGA and only specify width: .Pp .Dl $ nbfs2tga a.nbfs a.nbfp a.tga 64 .Pp Convert an NBFS+NBFP into a TGA and guess image dimensions: .Pp .Dl $ nbfs2tga a.nbfs a.nbfp a.tga .Sh SEE ALSO More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/ncgr2tga.1000066400000000000000000000046461331663051500165520ustar00rootroot00000000000000.Dd July 23, 2015 .Dt NCGR2TGA 1 .Os .Sh NAME .Nm ncgr2tga .Nd Nintendo NCGR image to TGA converter .Sh SYNOPSIS .Nm ncgr2tga .Op Ar options .Ar width height ncgr .Op Ar ngr ... .Ar nclr tga .Sh DESCRIPTION .Nm converts Nintendo's tile-based NCGR images into common TGA images. .Pp 2D graphics on the Nintendo DS is fundamentally tile-based. Specifically, the graphics data in NCGR is ordered in tiles of 8\(mu8 pixels. Moreover, an NCGR file can itself be a tile of a larger image. This tool can automatically combine and unwrap these tiles, and, together with an NCLR file for the palette, converts a grid of NCGR into a plain old linear TGA image. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .El .Bl -tag -width xx -compact .It Ar width The width of the NCGR grid, in NCGR files. .It Ar height The height of the NCGR grid, in NCGR files. .It Ar ncgr The name of an NCGR file to use. The NCGR contains the pixel graphics part of the image. .Pp width \(mu height NCGR files have to be given; they are drawn into the final TGA in row-major order. An empty filename, commonly specified with "", means that this grid cell will be empty, filled with palette entry 0. .It Ar nclr The name of the NCLR file to use. The NCLR file contains the palette part of the image. .It Ar tga The resulting TGA file will be written there. .El .Sh LIMITATIONS .Bl -bullet -compact .It Only NCGR files with version 1.1 are supported .It Only NCLR files with version 1.0 are supported .It Only palettes with bit-depths of 4 or 8 are supported .It Non-tiled or partitioned NCGR files are not supported .It Some NCGR files don't contain valid width/height values, and seem to need an NCER file for this information. These files are currently not supported .El .Sh EXAMPLES Convert a 2\(mu3 grid of NCGR files: .Bd -literal -offset xxxxxx $ ncgr2tga 2 3 a0.ncgr a1.ncgr a2.ncgr a3.ncgr a4.ncgr a5.ncgr \e a.nclr a.tga .Ed .Pp Convert a 2\(mu2 grid of NCGR files, leaving the lower left quadrant blank: .Pp .Dl $ ncgr2tga 2 2 b0.ncgr, b1.ncgr Qo \& Qc b2.ncgr b.nclr b.tga .Sh SEE ALSO .Xr cbgt2tga 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/ncsdis.1000066400000000000000000000107121331663051500163150ustar00rootroot00000000000000.Dd October 28, 2015 .Dt NCSDIS 1 .Os .Sh NAME .Nm ncsdis .Nd BioWare NWScript bytecode disassembler .Sh SYNOPSIS .Nm ncsdis .Op Ar options .Ar input_file .Op Ar output_file .Sh DESCRIPTION .Nm disassembles NCS files, compiled bytecode of the NWScript scripting language used by every single Aurora engine game, except for the Nintendo DS game .Em Sonic Chronicles: The Dark Brotherhood . The output, while not as clear as the C-like source code that produced the bytecode, is human-readable. .Pp .Nm is meant as a better maintainable and more complete replacement of the disassembly mode found in the OpenKnights nwnnsscomp tool. As such, it fixes provides these enhancements: .Bl -bullet -compact .It Compilable in 64-bit mode .It Out of the box support for all Aurora engine games .It Support for array opcodes added in .Em Dragon Age: Origins .It Support for reference opcodes added in .Em Dragon Age II .It Knowledge of additional variable types .It No need to provide an external nwscript.nss file .El .Pp Additionally, .Nm can create a dot file specifying a control flow graph of the disassembly. It can be plotted into a graph by the .Xr dot 1 tool of the GraphViz suite. .Pp .Sy WARNING : these graphs can get very large very quickly. To keep the resulting image small, set a small font and font size when calling GraphViz, and decrease the nodesep and ranksep values. .Pp Since there is no way to automatically detect for which game this script is, this information must be provided on the command. If no game is specified, the ACTION opcode that call an engine function, such as .Dq GetModule or trigonometry functions, will only display a number instead of a function name. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl list Create a full disassembly listing, including byte addresses and the raw bytecode, similar to the disassembly mode of nwnnsscomp. This is the default mode. .It Fl Fl assembly Only create the human-readable mnemonics part of the disassembly listing. Useful for modifying and extending the script. .It Fl Fl dot Create a flow control graph in the dot language, to be plotted by the GraphViz suite. .It Fl Fl stack Print the stack frame for each instruction. Only available in list or assembly mode, not in dot mode. .It Fl Fl control Print detected control structures inside block nodes. Only available in dot mode. .It Fl Fl nwn Use engine function tables of the game .Em Neverwinter Nights . .It Fl Fl nwn2 Use engine function tables of the game .Em Neverwinter Nights 2 . .It Fl Fl kotor Use engine function tables of the game .Em Star Wars: Knights of the Old Republic . .It Fl Fl kotor2 Use engine function tables of the game .Em Star Wars: Knights of the Old Republic II \(en The Sith Lords . .It Fl Fl jade Use engine function tables of the game .Em Jade Empire . .It Fl Fl witcher Use engine function tables of the game .Em The Witcher . .It Fl Fl dragonage Use engine function tables of the game .Em Dragon Age: Origins . .It Fl Fl dragonage2 Use engine function tables of the game .Em Dragon Age II . .El .Bl -tag -width xxxx -compact .It Ar input_file The NCS file to disassemble. .It Ar output_file The disassembly will be written there. If no output file is specified, the disassembly will be written to .Dv stdout . .El .Sh EXAMPLES Disassemble the script .Pa file.ncs : .Pp .Dl $ ncsdis file.ncs file.lst .Pp Disassemble the script .Pa file.ncs and write the listing to .Dv stdout : .Pp .Dl $ ncsdis file.ncs .Pp Disassemble the Jade Empire script .Pa file.ncs : .Pp .Dl $ ncsdis --jade file.ncs file.list .Pp Disassemble the Jade Empire script .Pa file.ncs in pure disassembly mode: .Pp .Dl $ ncsdis --assembly --jade file.ncs file.asm .Pp Create a dot graph file of the Neverwinter Nights script .Pa file.ncs : .Pp .Dl $ ncsdis --dot --nwn file.ncs file.dot .Pp Create a dot graph file of the Neverwinter Nights script .Pa file.ncs and plot it: .Bd -literal -offset xxxxxx $ ncsdis --dot --nwn file.ncs | dot -Gnodesep=0.1 -Granksep=0.1 \e -Gfontname="Courier New" -Nfontname="Courier New" -Gfontsize=10 \e -Nfontsize=8 -Earrowsize=0.5 -Tpng > file.png .Ed .Sh SEE ALSO .Xr dot 1 , .Xr nwnnsscomp 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/rules.mk000066400000000000000000000024441331663051500164360ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . # Man pages. dist_man1_MANS += \ man/cbgt2tga.1 \ man/cdpth2tga.1 \ man/convert2da.1 \ man/fixpremiumgff.1 \ man/desmall.1 \ man/gff2xml.1 \ man/nbfs2tga.1 \ man/ncgr2tga.1 \ man/tlk2xml.1 \ man/ssf2xml.1 \ man/xml2tlk.1 \ man/xml2ssf.1 \ man/unerf.1 \ man/unherf.1 \ man/unkeybif.1 \ man/unnds.1 \ man/unnsbtx.1 \ man/unrim.1 \ man/xoreostex2tga.1 \ man/ncsdis.1 \ man/erf.1 \ $(EMPTY) xoreos-tools-0.0.5/man/ssf2xml.1000066400000000000000000000036761331663051500164430ustar00rootroot00000000000000.Dd April 15, 2016 .Dt SSF2XML 1 .Os .Sh NAME .Nm ssf2xml .Nd BioWare SSF to XML converter .Sh SYNOPSIS .Nm ssf2xml .Op Ar options .Ar input_file .Op Ar output_file .Sh DESCRIPTION .Nm converts BioWare's SSF files into human-readable XML. SSF are .Dq sound sets , a list of voice lines uttered at certain situations, like attacking, getting hurt or picking a lock. Each line consists of an ID (denoting the position of the line within the SSF file), an optional StrRef (refering a textual line in a talk table) and an optional filename (which is the sound file to play). Additionally, each line may have a label attached which shows what the purpose of this line is. This label is purely for the benefit of the user reading the XML file and is not actually stored within the SSF. .Pp SSF files are used in .Em Neverwinter Nights , .Em Neverwinter Nights 2 , .Em Knights of the Old Republic and .Em Knights of the Old Republic II . However, the version of the format used in the latter two do not store any sound filenames, only StrRefs. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .El .Bl -tag -width xx -compact .It Ar input_file The SSF file to convert. .It Ar output_file The XML file will be written there. If no output file is specified, the XML data is written to .Dv stdout . The encoding of the XML stream is always UTF-8. .El .Sh EXAMPLES Convert the SSF .Pa file1.ssf into an XML file: .Pp .Dl $ ssf2xml file1.ssf file2.xml .Pp Convert the SSF .Pa file1.ssf into an XML file on .Dv stdout : .Pp .Dl $ ssf2xml file1.ssf .Sh "SEE ALSO" .Xr gff2xml 1 , .Xr tlk2xml 1 , .Xr xml2ssf 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/tlk2xml.1000066400000000000000000000114121331663051500164250ustar00rootroot00000000000000.Dd April 15, 2016 .Dt TLK2XML 1 .Os .Sh NAME .Nm tlk2xml .Nd BioWare TLK to XML converter .Sh SYNOPSIS .Nm tlk2xml .Op Ar options .Ar input_file .Op Ar output_file .Sh DESCRIPTION .Nm converts BioWare's TLK files into human-readable XML. TLK are .Dq talk tables , a list of strings indexed by an ID, used for all user-visible text in a BioWare game. All strings for a campaign or module are usually collected in one file for each supported language, and languages with sentences that vary wildly depending on whether the player character is male or female use a second TLK with strings for the female version. .Pp There's two distinct TLK formats. One is a whole separate file format (which uses version IDs V3.0 and V4.0), the other is a GFF (and uses version IDs V0.2 and V0.5). Within those two major versions, the differences are smaller: V4.0 removed fields for each string not needed anymore, and V0.5 compresses strings using a Huffman tree. This tool can read all of these variants and produces a human-read XML file. .Pp Because these files contain localized string data, it is important to know the encoding of those strings. Unfortunately, the TLK files do not contain information about the encoding. Version 3.0 and 4.0 contain a language identifier, but the meaning of that varies between games. V0.2 and V0.5 even lack those completely. However, due to the Huffman-nature of V0.5 strings, the encoding there is fixed to little-endian UTF-16, and strings in V0.2 files are also usually in little-endian UTF-16 (with the exceptions of files found in the Nintendo DS game .Em Sonic Chronicles: The Dark Brotherhood ) . To manually select the encoding, this tool provides a wide range command line options for various encodings. .Pp Alternatively, the game this TLK is from can be specified and .Nm will read the strings in an appropriate encoding for that game and the language ID found in the TLK. Please note that this does not work for the game .Em Sonic Chronicles: The Dark Brotherhood , since its TLK files do not provide a language ID. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl cp1250 Read strings as Windows CP-1250. Eastern European, Latin alphabet. .It Fl Fl cp1251 Read strings as Windows CP-1251. Eastern European, Cyrillic alphabet. .It Fl Fl cp1252 Read strings as Windows CP-1252. Western European, Latin alphabet. .It Fl Fl cp932 Read strings as Windows CP-932. Japanese, extended Shift-JIS. .It Fl Fl cp936 Read strings as Windows CP-936. Simplified Chinese, extended GB2312 with GBK codepoints. .It Fl Fl cp949 Read strings as Windows CP-949. Korean, similar to EUC-KR. .It Fl Fl cp950 Read strings as Windows CP-950. Traditional Chinese, similar to Big5. .It Fl Fl utf8 Read strings as UTF-8. .It Fl Fl utf16le Read strings as little-endian UTF-16. .It Fl Fl utf16be Read strings as big-endian UTF-16. .It Fl Fl nwn Read strings in an encoding appropriate for .Em Neverwinter Nights . .It Fl Fl nwn2 Read strings in an encoding appropriate for .Em Neverwinter Nights 2 . .It Fl Fl kotor Read strings in an encoding appropriate for .Em Knights of the Old Republic . .It Fl Fl kotor2 Read strings in an encoding appropriate for .Em Knights of the Old Republic II . .It Fl Fl jade Read strings in an encoding appropriate for .Em Jade Empire . .It Fl Fl witcher Read strings in an encoding appropriate for .Em The Witcher . .It Fl Fl dragonage Read strings in an encoding appropriate for .Em Dragon Age: Origins . .It Fl Fl dragonage2 Read strings in an encoding appropriate for .Em Dragon Age II . .El .Bl -tag -width xx -compact .It Ar input_file The TLK file to convert. .It Ar output_file The XML file will be written there. If no output file is specified, the XML data is written to .Dv stdout . The encoding of the XML stream is always UTF-8. .El .Sh EXAMPLES Convert the CP-1252 TLK .Pa file1.tlk into an XML file: .Pp .Dl $ tlk2xml --cp1252 file1.tlk file2.xml .Pp Convert the UTF-16LE TLK .Pa file1.tlk into an XML file on .Dv stdout : .Pp .Dl $ tlk2xml --utf16le file1.tlk .Pp Convert the TLK .Pa file1.tlk from Neverwinter Nights into an XML file: .Pp .Dl $ tlk2xml --nwn file1.tlk file2.xml .Pp Convert the UTF-8 TLK .Pa file1.tlk into an XML file on .Dv stdout , modify it using .Xr sed 1 and use .Xr xml2tlk 1 to write it back into a TLK: .Bd -literal -offset xxxxxx $ tlk2xml --utf8 file1.tlk | sed -e 's/gold/candy/g' | xml2tlk \e --utf8 --version30 file2.tlk .Ed .Sh "SEE ALSO" .Xr gff2xml 1 , .Xr ssf2xml 1 , .Xr xml2tlk 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/unerf.1000066400000000000000000000075571331663051500161660ustar00rootroot00000000000000.Dd June 27, 2018 .Dt UNERF 1 .Os .Sh NAME .Nm unerf .Nd BioWare ERF (.erf, .mod, .nwm, .sav) archive extractor .Sh SYNOPSIS .Nm unerf .Op Ar options .Ar command .Ar archive .Op Ar .Sh DESCRIPTION .Nm extracts BioWare ERF archives, found in many BioWare games as files with the extension .erf, .mod, .nwm or .sav. Moreover, in some games, a .rim file might be an ERF instead of a RIM. .Pp There's several different versions of ERFs. This tool supports the version V1.0, V1.1, V2.0, V2.2 and V3.0. .Pp Supported features: .Bl -bullet -compact .It Archives with stripped filenames. The name hash is searched for in a big lookup table. If it is not found, the file is listed and extracted as a hexadecimal representation of the hash .It zlib-compressed files are supported and transparently decompressed .It Blowfish-encrypted archives are supported and are, provided you know the password, transparently decrypted .It Archives that contain full paths are supported. You can either strip the directory and extract the plain filenames, or substitute the directory separator with a .Ql = .It Archives with numerical extension IDs belonging to different games can be aliased accordingly. .El .Pp Unsupported features: .Bl -bullet -compact .It XOR-encrypted archives .It Creating directories when extracting archives with full paths. .Pp Please also note that by stripped the directories of files in these archives, you might overwrite already extracted files .El .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl nwn2 Alias file types according to .Em Neverwinter Nights 2 rules. .Pp .Em Neverwinter Nights 2 reuses a few file extension IDs differently than other BioWare games. To correctly read Neverwinter Nights 2 ERF archives, use this flag. .It Fl Fl jade Alias file types according to .Em Jade Empire rules. .Pp .Em Jade Empire reuses a few file extension IDs differently than other BioWare games. To correctly read Jade Empire ERF archives, use this flag. .It Fl Fl pass Ar hex Password to decrypt this archive. This password needs to be specified in hexadecimal notation, even if it's an ASCII string. For example, .Dq 4CF223AB would be a valid password string. .Dq Foobar would not. .It Fl Fl nwm Ar file Calculate the MD5 of this NWM file to complement the decryption key of a HAK file for a Neverwinter Nights premium module. .El .Bl -tag -width xxxx -compact .It Ar command .Bl -tag -width xx -compact .It Cm i Display meta-information about the archive .It Cm l List archive contents .It Cm v List archive contents with full paths .It Cm e Extract files to current directory .It Cm s Extract files to current directory with full name .El .It Ar archive The ERF archive to read. .It Ar file One or more files to extract. If none are given, the whole archive is extracted. .El .Sh EXAMPLES View meta-information of the archive .Pa Shadowlords1.mod : .Pp .Dl $ unerf i Shadowlords1.mod .Pp List all files contained in the archive .Pa Chapter1.nwm : .Pp .Dl $ unerf l Chapter1.nwm .Pp List all files, with full path, in the archive .Pa areas.erf : .Pp .Dl $ unerf v areas.erf .Pp Extract all files from the archive .Pa foo.mod : .Pp .Dl $ unerf e foo.mod .Pp Extract the file .Pa area1.are from the archive .Pa foo.mod : .Pp .Dl $ unerf e foo.mod area1.are .Pp Extract all files, with full path, in the archive .Pa areas.erf : .Pp .Dl $ unerf s areas.erf .Pp Extract the file .Pa areas\earea1.are from the archive .Pa areas.erf : .Pp .Dl $ unerf s areas.erf areas\e\earea1.are .Sh SEE ALSO .Xr erf 1 , .Xr fixpremiumgff 1 , .Xr unherf 1 , .Xr unrim 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/unherf.1000066400000000000000000000026071331663051500163250ustar00rootroot00000000000000.Dd July 23, 2015 .Dt UNHERF 1 .Os .Sh NAME .Nm unherf .Nd BioWare HERF archive extractor .Sh SYNOPSIS .Nm unherf .Op Ar options .Ar command file .Sh DESCRIPTION .Nm extract BioWare HERF archives, found in the Nintendo DS game .Em Sonic Chronicles: The Dark Brotherhood . .Pp A HERF, Hashed ERF, is a very simple archive, similar to BioWare's ERF and RIM files. Unlike those, HERF usually only store djb2 hashes of the contained filenames. This tool has a lookup table to convert the hashes back into readable filenames. Not all names are known yet. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .El .Bl -tag -width xx -compact .It Ar command .Bl -tag -width xx -compact .It Cm l List archive contents .It Cm e Extract files to current directory .El .It Ar file The HERF archive to read. .El .Sh EXAMPLES List all files contained in the archive .Pa archive.herf : .Pp .Dl $ unherf l archive.herf .Pp Extract all files from the archive .Pa archive.herf : .Pp .Dl $ unherf e archive.herf .Sh SEE ALSO .Xr unerf 1 , .Xr unrim 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/unkeybif.1000066400000000000000000000045701331663051500166530ustar00rootroot00000000000000.Dd June 27, 2018 .Dt UNKEYBIF 1 .Os .Sh NAME .Nm unkeybif .Nd BioWare KEY/BIF archive extractor .Sh SYNOPSIS .Nm unkeybif .Op Ar options .Ar command .Ar .Sh DESCRIPTION .Nm extracts BioWare KEY/BIF archives, found in many BioWare games. .Pp KEY and BIF files are fundamentally linked: a KEY file contains file names and types, while the BIF file contains the file data itself. At the same time, a KEY file can control several BIF files. .Pp For example: .Pp .Pa foo.key controls: .Bl -bullet -compact .It .Pa foo1.bif .It .Pa foo2.bif .It .Pa foo3.bif .El .Pp .Pa foo.key indexes: .Bl -bullet -compact .It .Pa bar.are and .Pa bar.git from .Pa foo1.bif .It .Pa qux.utc from .Pa foo2.bif .It .Pa baz.txt from .Pa foo3.bif .El .Pp If you want to extract all files indexed by .Pa foo.key , you need to also specify .Pa foo1.bif , foo2.bif and .Pa foo3.bif on the command. If .Pa foo3.bif is missing, .Pa baz.txt will not be extracted. However, listing file only requires the KEY. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl nwn2 Alias file types according to .Em Neverwinter Nights 2 rules. .Pp .Em Neverwinter Nights 2 reuses a few file extension IDs differently than other BioWare games. To correctly read Neverwinter Nights 2 KEY/BIF archives, use this flag. .It Fl Fl jade Alias file types according to .Em Jade Empire rules. .Pp .Em Jade Empire reuses a few file extension IDs differently than other BioWare games. To correctly read Jade Empire KEY/BIF archives, use this flag. .El .Bl -tag -width xx -compact .It Ar command .Bl -tag -width xx -compact .It Cm l List archive contents .It Cm e Extract files to current directory .El .It Ar file A KEY or a BIF file to read. Multiple KEY and BIF files can be specified; they'll be considered a unit. .El .Sh EXAMPLES List all files indexed by the KEY file .Pa chitin.key : .Pp .Dl $ unkeybif l chitin.key .Pp Extract all files contained in .Pa data1.bif and .Pa data2.bif , that are indexed by .Pa chitin.key : .Pp .Dl $ unkeybif e chitin.key data1.bif data2.bif .Sh SEE ALSO More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/unnds.1000066400000000000000000000023151331663051500161610ustar00rootroot00000000000000.Dd July 23, 2015 .Dt UNNDS 1 .Os .Sh NAME .Nm unnds .Nd Nintendo DS archive extractor .Sh SYNOPSIS .Nm unnds .Op Ar options .Ar command .Ar file .Sh DESCRIPTION .Nm extract Nintendo DS ROMs. Only the resource files are extracted, not the executable binaries. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .El .Bl -tag -width xx -compact .It Ar command .Bl -tag -width xx -compact .It Cm i Display meta-information about the archive .It Cm l List archive contents .It Cm e Extract files to current directory .El .It Ar file The NDS archive to read. .El .Sh EXAMPLES View meta-information of the archive .Pa archive.nds : .Pp .Dl $ unnds i archive.nds .Pp List all files contained in the archive .Pa archive.nds : .Pp .Dl $ unnds l archive.nds .Pp Extract all files from the archive .Pa archive.nds : .Pp .Dl $ unnds e archive.nds .Sh SEE ALSO More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/unnsbtx.1000066400000000000000000000027441331663051500165410ustar00rootroot00000000000000.Dd July 23, 2015 .Dt UNNSBTX 1 .Os .Sh NAME .Nm unnsbtx .Nd Nintendo NSBTX texture extractor .Sh SYNOPSIS .Nm unnsbtx .Op Ar options .Ar command file .Sh DESCRIPTION .Nm treats Nintendo NSBTX texture as archives and converts the multiple images stored within into TGA files. The image pixel data and the palettes are automatically combined, provided they are named similarly. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .Fl Fl version Show version information and exit. .El .Bl -tag -width xx -compact .It Ar command .Bl -tag -width xx -compact .It Cm l List images inside this NSBTX texture .It Cm e Extract images as TGA files .El .It Ar file The NSBTX texture to read. .El .Sh LIMITATIONS The palette of an image has to be named similarly to the pixel data. Specifically, the palette has to be either named the same, or suffixed by .Dq _pl , .Dq _p or .Dq _ . If this not the case, and a palette for an image can't be found, .Nm throws an error. .Sh EXAMPLES List all images contained in the texture .Pa texture.nsbtx : .Pp .Dl $ unnsbtx l texture.nsbtx .Pp Extract all images contained in the texture .Pa texture.nsbtx : .Pp .Dl $ unnsbtx e texture.nsbtx .Sh SEE ALSO More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/unrim.1000066400000000000000000000031701331663051500161640ustar00rootroot00000000000000.Dd June 27, 2018 .Dt UNRIM 1 .Os .Sh NAME .Nm unrim .Nd BioWare RIM archive extractor .Sh SYNOPSIS .Nm unrim .Op Ar options .Ar command file .Sh DESCRIPTION .Nm extracts BioWare RIM archives, found in many BioWare games. .Pp RIM archives are simplified ERF archives, stripped of everything not related to holding files (like the description string). .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl nwn2 Alias file types according to .Em Neverwinter Nights 2 rules. .Pp .Em Neverwinter Nights 2 reuses a few file extension IDs differently than other BioWare games. To correctly read Neverwinter Nights 2 RIM archives, use this flag. .It Fl Fl jade Alias file types according to .Em Jade Empire rules. .Pp .Em Jade Empire reuses a few file extension IDs differently than other BioWare games. To correctly read Jade Empire RIM archives, use this flag. .El .Bl -tag -width xx -compact .It Ar command .Bl -tag -width xx -compact .It Cm l List archive contents .It Cm e Extract files to current directory .El .It Ar file The RIM archive to read. .El .Sh EXAMPLES List all files contained in the archive .Pa archive.rim : .Pp .Dl $ unrim l archive.rim .Pp Extract all files from the archive .Pa archive.rim : .Pp .Dl $ unrim e archive.rim .Sh SEE ALSO .Xr unerf 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/xml2ssf.1000066400000000000000000000057141331663051500164360ustar00rootroot00000000000000.Dd April 21, 2016 .Dt XML2SSF 1 .Os .Sh NAME .Nm xml2ssf .Nd XML to BioWare SSF converter .Sh SYNOPSIS .Nm xml2ssf .Op Ar options .Op Ar input_file .Ar output_file .Sh DESCRIPTION .Nm converts XML files created by the .Xr ssf2xml 1 tool back into the BioWare SSF format. For a more in-depth description of SSF files, please see the man page for the .Xr ssf2xml 1 tool. .Pp The format of the input XML is pretty simple and straight-forward. .Bd -literal vs_fkillerf_attk vs_fkillerf_bat1 .Ed .Pp The root element is .Dq ssf , with multiple .Dq sound elements as children. Each .Dq sound element requires an .Dq id property, specifying the index of the sound within the SSF file. Optionally, there can be a .Dq strref property, which denotes the string reference (StrRef) of the text line associated with the sound. The contents of the .Dq sound element is the filename (ResRef) of the sound file to play. .Pp Because different BioWare games use slightly different versions of the SSF file format, the game for which to create the SSF file has to be specifying on the command line. Please note that the file versions have different requirements on the input data as well. These requirements are noted below. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl Fl nwn Create an SSF file fit for use within the game .Em Neverwinter Nights . Sound filenames have to be 16 characters long or less. .It Fl Fl nwn2 Create an SSF file fit for use within the game .Em Neverwinter Nights 2 . Sound filenames have to be 32 characters long or less. .It Fl Fl kotor Create an SSF file fit for use within the game .Em Knights of the Old Republic . No sound filenames are allowed, only StrRefs. .It Fl Fl kotor2 Create an SSF file fit for use within the game .Em Knights of the Old Republic II . No sound filenames are allowed, only StrRefs. .El .Bl -tag -width xxxx -compact .It Ar input_file The XML file to convert. If no input file is specified, the XML data is read from .Dv stdin . The encoding of the XML stream must always be UTF-8. .It Ar output_file The SSF file will be written there. .El .Sh EXAMPLES Convert .Pa file1.xml into an SSF for Neverwinter Nights: .Pp .Dl $ xml2ssf --nwn file1.xml file2.ssf .Pp Convert .Pa file1.xml into an SSF for Knights of the Old Republic: .Pp .Dl $ xml2ssf --kotor file1.xml file2.ssf .Sh SEE ALSO .Xr ssf2xml 1 , .Xr xml2tlk 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/xml2tlk.1000066400000000000000000000136411331663051500164330ustar00rootroot00000000000000.Dd July 23, 2015 .Dt XML2TLK 1 .Os .Sh NAME .Nm xml2tlk .Nd XML to BioWare TLK converter .Sh SYNOPSIS .Nm xml2tlk .Op Ar options .Op Ar input_file .Ar output_file .Sh DESCRIPTION .Nm converts XML files created by the .Xr tlk2xml 1 tool back into the BioWare TLK format. For a more in-depth description of TLK files, please see the man page for the .Xr tlk2xml 1 tool. Also note that currently, only the non-GFF versions, V3.0 and V4.0, can be created by xml2tlk. .Pp The format of the input XML is pretty simple and straight-forward. .Bd -literal Continue Well hello there! Bye! Who are you? .Ed .Pp The root element is .Dq tlk , and it can have an optional language property. That language ID can also be given on the command line, and it then overrides the one in the input XML. When creating a, versions V3.0 and V4.0 need a language ID, while versions V0.2 and V0.5 ignore the language ID. .Pp Each child tag of the root element has to be a .Dq string element, and each .Dq string element requires an .Dq id property. The ID is the string reference (StrRef) for the text line, and the contents of the .Dq string element is the text itself. The whole file has to be UTF-8 encoded. .Pp Version V3.0 allows the following extra properties on a .Dq string : .Dq sound (a resource reference of a voice-over for this line, \(<=\ 16 characters), .Dq soundlength (a floating point number denoting the length of the sound file in seconds), .Dq volumevariance (unused by the games) and .Dq pitchvariance (unused by the games). .Pp Version V4.0 allows the extra property .Dq soundid on a .Dq string , which is a numerical references to a voice-over line. .Pp Versions V0.2 and V0.5 do not allow any extra properties. .Pp Because TLK files contain localized string data, it is important to know the encoding of those strings. Unfortunately, the TLK files do not contain information about the encoding. Version 3.0 and 4.0 contain a language identifier, but the meaning of that varies between games. V0.2 and V0.5 even lack those completely. However, due to the Huffman-nature of V0.5 strings, the encoding there is fixed to little-endian UTF-16, and strings in V0.2 files are also usually in little-endian UTF-16 (with the exceptions of files found in the Nintendo DS game .Em Sonic Chronicles: The Dark Brotherhood ) . To manually select the encoding, this tool provides a wide range command line options for various encodings. .Pp Alternatively, the game this TLK is from can be specified and .Nm will write the strings in an appropriate encoding for that game and the language ID. Please note that this does not work for the game .Em Sonic Chronicles: The Dark Brotherhood , since its TLK files do not provide a language ID. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl 3 .It Fl Fl version30 Write a V3.0 TLK file. .It Fl 4 .It Fl Fl version40 Write a V4.0 TLK file. .It Fl l Ar id .It Fl Fl language Ar id Override the TLK language ID. .It Fl Fl cp1250 Write strings as Windows CP-1250. .Pp Eastern European, Latin alphabet. .It Fl Fl cp1251 Write strings as Windows CP-1251. .Pp Eastern European, Cyrillic alphabet. .It Fl Fl cp1252 Write strings as Windows CP-1252. .Pp Western European, Latin alphabet. .It Fl Fl cp932 Write strings as Windows CP-932. .Pp Japanese, extended Shift-JIS. .It Fl Fl cp936 Write strings as Windows CP-936. .Pp Simplified Chinese, extended GB2312 with GBK codepoints. .It Fl Fl cp949 Write strings as Windows CP-949. .Pp Korean, similar to EUC-KR. .It Fl Fl cp950 Write strings as Windows CP-950. .Pp Traditional Chinese, similar to Big5. .It Fl Fl utf8 Write strings as UTF-8. .It Fl Fl utf16le Write strings as little-endian UTF-16. .It Fl Fl utf16be Write strings as big-endian UTF-16. .It Fl Fl nwn Write strings in an encoding appropriate for .Em Neverwinter Nights . .It Fl Fl nwn2 Write strings in an encoding appropriate for .Em Neverwinter Nights 2 . .It Fl Fl kotor Write strings in an encoding appropriate for .Em Knights of the Old Republic . .It Fl Fl kotor2 Write strings in an encoding appropriate for .Em Knights of the Old Republic II . .It Fl Fl jade Write strings in an encoding appropriate for .Em Jade Empire . .It Fl Fl witcher Write strings in an encoding appropriate for .Em The Witcher . .It Fl Fl dragonage Write strings in an encoding appropriate for .Em Dragon Age: Origins . .It Fl Fl dragonage2 Write strings in an encoding appropriate for .Em Dragon Age II . .El .Bl -tag -width xxxx -compact .It Ar input_file The XML file to convert. If no input file is specified, the XML data is read from .Dv stdin . The encoding of the XML stream must always be UTF-8. .It Ar output_file The TLK file will be written there. .El .Sh EXAMPLES Convert .Pa file1.xml into a V3.0 CP-1252 TLK file: .Pp .Dl $ xml2tlk --version30 --cp1252 file1.xml file2.tlk .Pp Convert .Pa file1.xml into a V4.0 UTF-8 TLK file and override the language ID: .Pp .Dl $ xml2tlk --version40 --utf8 --language 1 file1.xml file2.tlk .Pp Convert .Pa file1.xml into a V3.0 TLK file from Neverwinter Nights: .Pp .Dl $ xml2tlk --version30 --nwn file1.xml file2.tlk .Pp Convert the UTF-8 TLK .Pa file1.tlk into an XML file on .Dv stdout with .Xr tlk2xml 1 , modify it using .Xr sed 1 and write the result back into a TLK: .Bd -literal -offset xxxxxx $ tlk2xml --utf8 file1.tlk | sed -e 's/gold/candy/g' | xml2tlk \e --utf8 --version30 file2.tlk .Ed .Sh SEE ALSO .Xr tlk2xml 1 , .Xr xml2ssf 1 .Pp More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/man/xoreostex2tga.1000066400000000000000000000044661331663051500176610ustar00rootroot00000000000000.Dd July 23, 2015 .Dt XOREOSTEX2TGA 1 .Os .Sh NAME .Nm xoreostex2tga .Nd BioWare textures to TGA converter .Sh SYNOPSIS .Nm xoreostex2tga .Op Ar options .Ar input_file output_file .Sh DESCRIPTION .Nm converts textures of various formats found in BioWare games into plain TGA images. .Pp Supported formats: .Bl -tag -compact -width Ds .It DDS Both the common DirectDraw Surface format and BioWare's own, completely different DDS format are supported, each with a variety of pixel formats .It SBM Found in .Em Jade Empire , holding font glyphs .It TXB Textures in .Em Jade Empire and the Xbox version of .Em Knights of the Old Republic .It TPC Textures in other versions of .Em Knights of the Old Republic . .It TGA Textures in various games, in many different pixels formats .El .Pp The output format is always either 24-bit or 32-bit BGR(A) TGA, depending on whether the input file has an alpha channel or not. Only the highest resolution mip map will be used. .Sh OPTIONS .Bl -tag -width xxxx -compact .It Fl h .It Fl Fl help Show a help text and exit. .It Fl Fl version Show version information and exit. .It Fl f .It Fl Fl flip Flip the image vertically while converting. .It Fl Fl auto Try to autodetect the format of the input file. This is the default mode of operation. .It Fl Fl dds Explicitly mark the input file as DDS. .It Fl Fl sbm Explicitly mark the input file as SBM. .It Fl Fl tpc Explicitly mark the input file as TPC. .It Fl Fl txb Explicitly mark the input file as TXB. .It Fl Fl tga Explicitly mark the input file as TGA. .El .Bl -tag -width xxxx -compact .It Ar input_file The name of the texture file to read. .It Ar output_file The resulting TGA file will be written there. .El .Sh EXAMPLES Convert .Pa texture.dds into .Pa image.tga : .Pp .Dl $ xoreostex2tga texture.dds image.tga .Pp Convert .Pa texture.dds into .Pa image.tga and flip the image: .Pp .Dl $ xoreostex2tga --flip texture.dds image.tga .Pp Convert the TPC .Pa texture.txb into .Pa image.tga and flip the image: .Pp .Dl $ xoreostex2tga --flip --tpc texture.txb image.tga .Sh SEE ALSO More information about the xoreos project can be found on .Lk https://xoreos.org/ "its website" . .Sh AUTHORS This program is part of the xoreos-tools package, which in turn is part of the xoreos project, and was written by the xoreos team. Please see the .Pa AUTHORS file for details. xoreos-tools-0.0.5/rules.mk000066400000000000000000000027721331663051500156670ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . # Top-level automake build recipe. # Extra files to help with the sources EXTRA_DIST += \ BUILDDEP.md \ .uncrustifyrc \ $(EMPTY) # Extra autotools files EXTRA_DIST += \ autogen.sh \ $(EMPTY) # Files for CMake, our alternative build system EXTRA_DIST += \ CMakeLists.txt \ cmake/CMakeAM.cmake \ cmake/CMakeUninstall.cmake \ cmake/FindIconv.cmake \ cmake/SetCheckCompilerFlag.cmake \ cmake/toolchain/i686-windows-mingw.cmake \ cmake/toolchain/x86_64-windows-mingw.cmake \ $(EMPTY) # Subdirectories include dists/rules.mk include man/rules.mk include doc/rules.mk include utf8cpp/rules.mk include src/rules.mk include tests/rules.mk xoreos-tools-0.0.5/src/000077500000000000000000000000001331663051500147635ustar00rootroot00000000000000xoreos-tools-0.0.5/src/aurora/000077500000000000000000000000001331663051500162545ustar00rootroot00000000000000xoreos-tools-0.0.5/src/aurora/2dafile.cpp000066400000000000000000000437141331663051500202770ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's 2DAs (two-dimensional array). */ /* See BioWare's own specs released for Neverwinter Nights modding * () */ #include #include "src/common/util.h" #include "src/common/error.h" #include "src/common/scopedptr.h" #include "src/common/strutil.h" #include "src/common/encoding.h" #include "src/common/readstream.h" #include "src/common/writefile.h" #include "src/common/streamtokenizer.h" #include "src/aurora/types.h" #include "src/aurora/2dafile.h" #include "src/aurora/gdafile.h" #include "src/aurora/gdaheaders.h" #include "src/aurora/gff4file.h" static const uint32 k2DAID = MKTAG('2', 'D', 'A', ' '); static const uint32 k2DAIDTab = MKTAG('2', 'D', 'A', '\t'); static const uint32 kVersion2a = MKTAG('V', '2', '.', '0'); static const uint32 kVersion2b = MKTAG('V', '2', '.', 'b'); namespace Aurora { TwoDARow::TwoDARow(TwoDAFile &parent) : _parent(&parent) { } TwoDARow::~TwoDARow() { } const Common::UString &TwoDARow::getString(size_t column) const { const Common::UString &cell = getCell(column); if (cell.empty() || (cell == "****")) return _parent->_defaultString; return cell; } const Common::UString &TwoDARow::getString(const Common::UString &column) const { const Common::UString &cell = getCell(_parent->headerToColumn(column)); if (cell.empty() || (cell == "****")) return _parent->_defaultString; return cell; } int32 TwoDARow::getInt(size_t column) const { const Common::UString &cell = getCell(column); if (cell.empty() || (cell == "****")) return _parent->_defaultInt; return _parent->parseInt(cell); } int32 TwoDARow::getInt(const Common::UString &column) const { const Common::UString &cell = getCell(_parent->headerToColumn(column)); if (cell.empty() || (cell == "****")) return _parent->_defaultInt; return _parent->parseInt(cell); } float TwoDARow::getFloat(size_t column) const { const Common::UString &cell = getCell(column); if (cell.empty() || (cell == "****")) return _parent->_defaultFloat; return _parent->parseFloat(cell); } float TwoDARow::getFloat(const Common::UString &column) const { const Common::UString &cell = getCell(_parent->headerToColumn(column)); if (cell.empty() || (cell == "****")) return _parent->_defaultFloat; return _parent->parseFloat(cell); } bool TwoDARow::empty(size_t column) const { const Common::UString &cell = getCell(column); if (cell.empty() || (cell == "****")) return true; return false; } bool TwoDARow::empty(const Common::UString &column) const { return empty(_parent->headerToColumn(column)); } static const Common::UString kEmpty; const Common::UString &TwoDARow::getCell(size_t n) const { if (n >= _data.size()) return kEmpty; return _data[n]; } TwoDAFile::TwoDAFile(Common::SeekableReadStream &twoda) : _defaultInt(0), _defaultFloat(0.0f), _emptyRow(*this) { load(twoda); } TwoDAFile::TwoDAFile(const GDAFile &gda) : _defaultInt(0), _defaultFloat(0.0f), _emptyRow(*this) { load(gda); } TwoDAFile::~TwoDAFile() { } void TwoDAFile::load(Common::SeekableReadStream &twoda) { readHeader(twoda); if ((_id != k2DAID) && (_id != k2DAIDTab)) throw Common::Exception("Not a 2DA file (%s)", Common::debugTag(_id).c_str()); if ((_version != kVersion2a) && (_version != kVersion2b)) throw Common::Exception("Unsupported 2DA file version %s", Common::debugTag(_version).c_str()); // Ignore the rest of the line; it's garbage Common::readStringLine(twoda, Common::kEncodingASCII); try { if (_version == kVersion2a) read2a(twoda); // ASCII else if (_version == kVersion2b) read2b(twoda); // Binary // Create the map to quickly translate headers to column indices createHeaderMap(); } catch (Common::Exception &e) { e.add("Failed reading 2DA file"); throw; } } void TwoDAFile::read2a(Common::SeekableReadStream &twoda) { Common::StreamTokenizer tokenize(Common::StreamTokenizer::kRuleIgnoreAll); // Spaces and tabs act to separate cells tokenize.addSeparator(' '); tokenize.addSeparator('\t'); // We can quote spaces and tabs with " tokenize.addQuote('\"'); // \n ends a whole row tokenize.addChunkEnd('\n'); // We're ignoring \r tokenize.addIgnore('\r'); readDefault2a(twoda, tokenize); readHeaders2a(twoda, tokenize); readRows2a(twoda, tokenize); } void TwoDAFile::read2b(Common::SeekableReadStream &twoda) { readHeaders2b(twoda); skipRowNames2b(twoda); readRows2b(twoda); } void TwoDAFile::readDefault2a(Common::SeekableReadStream &twoda, Common::StreamTokenizer &tokenize) { /* ASCII 2DA files can have default values that are returned for cells * that don't exist. They are specified in the second line, optionally * preceded by "Default:". */ std::vector defaultRow; tokenize.getTokens(twoda, defaultRow, 2); if (defaultRow[0].equalsIgnoreCase("Default:")) _defaultString = defaultRow[1]; _defaultInt = parseInt(_defaultString); _defaultFloat = parseFloat(_defaultString); tokenize.nextChunk(twoda); } void TwoDAFile::readHeaders2a(Common::SeekableReadStream &twoda, Common::StreamTokenizer &tokenize) { /* Read the column headers of an ASCII 2DA file. */ while (!twoda.eos() && (tokenize.getTokens(twoda, _headers) == 0)) tokenize.nextChunk(twoda); tokenize.nextChunk(twoda); } void TwoDAFile::readRows2a(Common::SeekableReadStream &twoda, Common::StreamTokenizer &tokenize) { /* And now read the individual cells in the rows. */ const size_t columnCount = _headers.size(); while (!twoda.eos()) { Common::ScopedPtr row(new TwoDARow(*this)); /* Skip the first token, which is the row index, possibly indented. * The row index is implicit in the data and its use in the 2DA * file is only meant as a guideline for people editing the file by * hand. It might even be completely incorrect. */ tokenize.findFirstToken(twoda); tokenize.skipToken(twoda); // Read all the cells in the row size_t count = tokenize.getTokens(twoda, row->_data, columnCount, columnCount, "****"); // And move to the next line tokenize.nextChunk(twoda); // Ignore empty lines if (count == 0) continue; _rows.push_back(row.release()); } } void TwoDAFile::readHeaders2b(Common::SeekableReadStream &twoda) { /* Read the column headers of a binary 2DA file. */ Common::StreamTokenizer tokenize(Common::StreamTokenizer::kRuleHeed); // Individual column headers a separated by either a tab or a NUL tokenize.addSeparator('\t'); tokenize.addSeparator('\0'); Common::UString header = tokenize.getToken(twoda); while (!header.empty()) { _headers.push_back(header); header = tokenize.getToken(twoda); } } void TwoDAFile::skipRowNames2b(Common::SeekableReadStream &twoda) { /* Next up are the row names / indices. Like for the ASCII 2DA files, * the actual row indices are implicit in the data, so we're just * ignoring them. The only information we care about is how many rows * there are. */ const uint32 rowCount = twoda.readUint32LE(); _rows.resize(rowCount, 0); Common::StreamTokenizer tokenize(Common::StreamTokenizer::kRuleHeed); // Individual row indices a separated by either a tab or a NUL tokenize.addSeparator('\t'); tokenize.addSeparator('\0'); tokenize.skipToken(twoda, rowCount); } void TwoDAFile::readRows2b(Common::SeekableReadStream &twoda) { /* And now read the cells. In binary 2DA files, each cell only * stores a single 16-bit number, the offset into the data segment * where the data for this cell can be found. Moreover, a single * data offset can be used by several cells, deduplicating the * cell data. */ const size_t columnCount = _headers.size(); const size_t rowCount = _rows.size(); const size_t cellCount = columnCount * rowCount; Common::ScopedArray offsets(new uint32[cellCount]); Common::StreamTokenizer tokenize(Common::StreamTokenizer::kRuleHeed); tokenize.addSeparator('\0'); for (size_t i = 0; i < cellCount; i++) offsets[i] = twoda.readUint16LE(); twoda.skip(2); // Size of the data segment in bytes const size_t dataOffset = twoda.pos(); for (size_t i = 0; i < rowCount; i++) { _rows[i] = new TwoDARow(*this); _rows[i]->_data.resize(columnCount); for (size_t j = 0; j < columnCount; j++) { const size_t offset = dataOffset + offsets[i * columnCount + j]; twoda.seek(offset); _rows[i]->_data[j] = tokenize.getToken(twoda); if (_rows[i]->_data[j].empty()) _rows[i]->_data[j] = "****"; } } } void TwoDAFile::createHeaderMap() { for (size_t i = 0; i < _headers.size(); i++) _headerMap.insert(std::make_pair(_headers[i], i)); } void TwoDAFile::load(const GDAFile &gda) { try { const GDAFile::Headers &headers = gda.getHeaders(); assert(headers.size() == gda.getColumnCount()); _headers.resize(gda.getColumnCount()); for (size_t i = 0; i < gda.getColumnCount(); i++) { const char *headerString = findGDAHeader(headers[i].hash); _headers[i] = headerString ? headerString : Common::UString::format("[%u]", headers[i].hash); } _rows.resize(gda.getRowCount(), 0); for (size_t i = 0; i < gda.getRowCount(); i++) { const GFF4Struct *row = gda.getRow(i); _rows[i] = new TwoDARow(*this); _rows[i]->_data.resize(gda.getColumnCount()); for (size_t j = 0; j < gda.getColumnCount(); j++) { if (row) { switch (headers[j].type) { case GDAFile::kTypeString: case GDAFile::kTypeResource: _rows[i]->_data[j] = row->getString(headers[j].field); break; case GDAFile::kTypeInt: _rows[i]->_data[j] = Common::UString::format("%d", (int) row->getSint(headers[j].field)); break; case GDAFile::kTypeFloat: _rows[i]->_data[j] = Common::UString::format("%f", row->getDouble(headers[j].field)); break; case GDAFile::kTypeBool: _rows[i]->_data[j] = Common::UString::format("%u", (uint) row->getUint(headers[j].field)); break; default: break; } } if (_rows[i]->_data[j].empty()) _rows[i]->_data[j] = "****"; } } } catch (Common::Exception &e) { e.add("Failed reading GDA file"); throw; } createHeaderMap(); } size_t TwoDAFile::getRowCount() const { return _rows.size(); } size_t TwoDAFile::getColumnCount() const { return _headers.size(); } const std::vector &TwoDAFile::getHeaders() const { return _headers; } size_t TwoDAFile::headerToColumn(const Common::UString &header) const { HeaderMap::const_iterator column = _headerMap.find(header); if (column == _headerMap.end()) // No such header return kFieldIDInvalid; return column->second; } const TwoDARow &TwoDAFile::getRow(size_t row) const { if ((row >= _rows.size()) || !_rows[row]) // No such row return _emptyRow; return *_rows[row]; } const TwoDARow &TwoDAFile::getRow(const Common::UString &header, const Common::UString &value) const { size_t columnIndex = headerToColumn(header); if (columnIndex == kFieldIDInvalid) return _emptyRow; for (std::vector::const_iterator row = _rows.begin(); row != _rows.end(); ++row) { if ((*row)->getString(columnIndex).equalsIgnoreCase(value)) return **row; } // No such row return _emptyRow; } void TwoDAFile::writeASCII(Common::WriteStream &out) const { // Write header out.writeString("2DA V2.0\n"); if (!_defaultString.empty()) out.writeString(Common::UString::format("DEFAULT: %s", _defaultString.c_str())); out.writeByte('\n'); // Calculate column lengths std::vector colLength; colLength.resize(_headers.size() + 1, 0); const Common::UString maxRow = Common::UString::format("%d", (int)_rows.size() - 1); colLength[0] = maxRow.size(); for (size_t i = 0; i < _headers.size(); i++) colLength[i + 1] = _headers[i].size(); for (size_t i = 0; i < _rows.size(); i++) { for (size_t j = 0; j < _rows[i]->_data.size(); j++) { const bool needQuote = _rows[i]->_data[j].contains(' '); const size_t length = needQuote ? _rows[i]->_data[j].size() + 2 : _rows[i]->_data[j].size(); colLength[j + 1] = MAX(colLength[j + 1], length); } } // Write column headers out.writeString(Common::UString::format("%-*s", (int)colLength[0], "")); for (size_t i = 0; i < _headers.size(); i++) out.writeString(Common::UString::format(" %-*s", (int)colLength[i + 1], _headers[i].c_str())); out.writeByte('\n'); // Write array for (size_t i = 0; i < _rows.size(); i++) { out.writeString(Common::UString::format("%*u", (int)colLength[0], (uint)i)); for (size_t j = 0; j < _rows[i]->_data.size(); j++) { const bool needQuote = _rows[i]->_data[j].contains(' '); Common::UString cellString; if (needQuote) cellString = Common::UString::format("\"%s\"", _rows[i]->_data[j].c_str()); else cellString = _rows[i]->_data[j]; out.writeString(Common::UString::format(" %-*s", (int)colLength[j + 1], cellString.c_str())); } out.writeByte('\n'); } out.flush(); } bool TwoDAFile::writeASCII(const Common::UString &fileName) const { Common::WriteFile file; if (!file.open(fileName)) return false; writeASCII(file); file.close(); return true; } void TwoDAFile::writeBinary(Common::WriteStream &out) const { const size_t columnCount = _headers.size(); const size_t rowCount = _rows.size(); const size_t cellCount = columnCount * rowCount; out.writeString("2DA V2.b\n"); // Write the column headers for (std::vector::const_iterator h = _headers.begin(); h != _headers.end(); ++h) { out.writeString(*h); out.writeByte('\t'); } out.writeByte('\0'); // Write the row indices out.writeUint32LE((uint32) rowCount); for (size_t i = 0; i < rowCount; i++) { out.writeString(Common::composeString(i)); out.writeByte('\t'); } /* Deduplicate cell data strings. Binary 2DA files don't store the * data for each cell directly: instead, each cell contains an offset * into a data array. This way, cells with the same data only need to * to store this data once. * * The original binary 2DA files in KotOR/KotOR2 make extensive use * of that, and we should do this as well. * * Basically, this involves going through each cell, and looking up * if we already saved this particular piece of data. If not, save * it, otherwise only remember the offset. There's no need to be * particularly smart about it, so we're just doing it the naive * O(n^2) way. */ std::vector data; std::vector offsets; data.reserve(cellCount); offsets.reserve(cellCount); size_t dataSize = 0; std::vector cells; cells.reserve(cellCount); for (size_t i = 0; i < rowCount; i++) { assert(_rows[i]); for (size_t j = 0; j < columnCount; j++) { const Common::UString cell = _rows[i]->getString(j); // Do we already know about this cell data string? size_t foundCell = SIZE_MAX; for (size_t k = 0; k < data.size(); k++) { if (data[k] == cell) { foundCell = k; break; } } // If not, add it to the cell data array if (foundCell == SIZE_MAX) { foundCell = data.size(); data.push_back(cell); offsets.push_back(dataSize); dataSize += data.back().size() + 1; if (dataSize > 65535) throw Common::Exception("TwoDAFile::writeBinary(): Cell data size overflow"); } // Remember the offset to the cell data array cells.push_back(offsets[foundCell]); } } // Write cell data offsets for (std::vector::const_iterator c = cells.begin(); c != cells.end(); ++c) out.writeUint16LE((uint16) *c); // Size of the all cell data strings out.writeUint16LE((uint16) dataSize); // Write cell data strings for (std::vector::const_iterator d = data.begin(); d != data.end(); ++d) { out.writeString(*d); out.writeByte('\0'); } } bool TwoDAFile::writeBinary(const Common::UString &fileName) const { Common::WriteFile file; if (!file.open(fileName)) return false; writeBinary(file); file.close(); return true; } void TwoDAFile::writeCSV(Common::WriteStream &out) const { // Write column headers for (size_t i = 0; i < _headers.size(); i++) { const bool needQuote = _headers[i].contains(','); if (needQuote) out.writeByte('"'); out.writeString(_headers[i]); if (needQuote) out.writeByte('"'); if (i < (_headers.size() - 1)) out.writeByte(','); } out.writeByte('\n'); // Write array for (size_t i = 0; i < _rows.size(); i++) { for (size_t j = 0; j < _rows[i]->_data.size(); j++) { const bool needQuote = _rows[i]->_data[j].contains(','); if (needQuote) out.writeByte('"'); if (_rows[i]->_data[j] != "****") out.writeString(_rows[i]->_data[j]); if (needQuote) out.writeByte('"'); if (j < (_rows[i]->_data.size() - 1)) out.writeByte(','); } out.writeByte('\n'); } out.flush(); } bool TwoDAFile::writeCSV(const Common::UString &fileName) const { Common::WriteFile file; if (!file.open(fileName)) return false; writeCSV(file); file.close(); return true; } int32 TwoDAFile::parseInt(const Common::UString &str) { if (str.empty()) return 0; int32 v = 0; try { Common::parseString(str, v); } catch (...) { } return v; } float TwoDAFile::parseFloat(const Common::UString &str) { if (str.empty()) return 0; float v = 0.0f; try { Common::parseString(str, v); } catch (...) { } return v; } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/2dafile.h000066400000000000000000000152461331663051500177430ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's 2DAs (two-dimensional array). */ #ifndef AURORA_2DAFILE_H #define AURORA_2DAFILE_H #include #include #include #include "src/common/types.h" #include "src/common/deallocator.h" #include "src/common/ptrvector.h" #include "src/common/ustring.h" #include "src/aurora/aurorafile.h" namespace Common { class SeekableReadStream; class WriteStream; class StreamTokenizer; } namespace Aurora { class TwoDAFile; class GDAFile; /** A row within a 2DA file. * * Each row inside a 2DA file contains several cells with string * data, identified by either their column index or column header * string. * * For convenience's sake, there are also methods to directly parse * the cell strings into integer or floating point values. * * See also class TwoDAFile. */ class TwoDARow : boost::noncopyable { public: /** Return the contents of a cell as a string. */ const Common::UString &getString(size_t column) const; /** Return the contents of a cell as a string. */ const Common::UString &getString(const Common::UString &column) const; /** Return the contents of a cell as an int. */ int32 getInt(size_t column) const; /** Return the contents of a cell as an int. */ int32 getInt(const Common::UString &column) const; /** Return the contents of a cell as a float. */ float getFloat(size_t column) const; /** Return the contents of a cell as a float. */ float getFloat(const Common::UString &column) const; /** Check if the cell is empty. */ bool empty(size_t column) const; /** Check if the cell is empty. */ bool empty(const Common::UString &column) const; private: TwoDAFile *_parent; ///< The parent 2DA. std::vector _data; TwoDARow(TwoDAFile &parent); ~TwoDARow(); const Common::UString &getCell(size_t n) const; friend class TwoDAFile; template friend void Common::DeallocatorDefault::destroy(T *); }; /** Class to hold the two-dimensional array of a 2DA file. * * A 2DA contains a two-dimensional array of string data, where * each cell can be identified by the numerical index of its row * and column. Moreover, each column has a textual "header", a * string uniquely identifying the column by what it's used for. * * The usual use-case is to first identify which row to use for * a certain object, item, feat, etc., read this row out of the * 2DA, and then read each column cell in that row. * * For example: the data file defining an item specifies a "Type" * of 23, which is an index into the row 23 of the 2DA "items.2da". * This 2DA contains the column "Model", "Icon" and "Price", so * the cells in the row 23 contain the model, icon and price of * the item we are looking for. * * 2DA files exist in two variants: ASCII and binary. The ASCII * version is just a simple text file, formatted to represent a * grid of data, with whitespace separating the cells. It can * be read and modified with a simple text editor. The binary * version cannot. * * See also classes TwoDARow and TwoDARegistry. */ class TwoDAFile : boost::noncopyable, public AuroraFile { public: TwoDAFile(Common::SeekableReadStream &twoda); TwoDAFile(const GDAFile &gda); ~TwoDAFile(); /** Return the number of rows in the array. */ size_t getRowCount() const; /** Return the number of columns in the array. */ size_t getColumnCount() const; /** Return the columns' headers. */ const std::vector &getHeaders() const; /** Translate a column header to a column index. */ size_t headerToColumn(const Common::UString &header) const; /** Get a row. */ const TwoDARow &getRow(size_t row) const; /** Get a row whose value in the column named header is the given string value. */ const TwoDARow &getRow(const Common::UString &header, const Common::UString &value) const; // .--- 2DA file writers /** Write the 2DA data into an V2.0 ASCII 2DA. */ void writeASCII(Common::WriteStream &out) const; /** Write the 2DA data into an V2.0 ASCII 2DA. */ bool writeASCII(const Common::UString &fileName) const; /** Write the 2DA data into an V2.b binary 2DA. */ void writeBinary(Common::WriteStream &out) const; /** Write the 2DA data into an V2.b binary 2DA. */ bool writeBinary(const Common::UString &fileName) const; /** Write the 2DA data into a CSV stream. */ void writeCSV(Common::WriteStream &out) const; /** Write the 2DA data into a CSV file. */ bool writeCSV(const Common::UString &fileName) const; // '--- private: typedef std::map HeaderMap; Common::UString _defaultString; ///< The default string to return should a cell not exist. int32 _defaultInt; ///< The default int to return should a cell not exist. float _defaultFloat; ///< The default float to return should a cell not exist. std::vector _headers; HeaderMap _headerMap; TwoDARow _emptyRow; Common::PtrVector _rows; // Loading helpers void load(Common::SeekableReadStream &twoda); void read2a(Common::SeekableReadStream &twoda); void read2b(Common::SeekableReadStream &twoda); // ASCII loading helpers void readDefault2a(Common::SeekableReadStream &twoda, Common::StreamTokenizer &tokenize); void readHeaders2a(Common::SeekableReadStream &twoda, Common::StreamTokenizer &tokenize); void readRows2a (Common::SeekableReadStream &twoda, Common::StreamTokenizer &tokenize); // Binary loading helpers void readHeaders2b (Common::SeekableReadStream &twoda); void skipRowNames2b(Common::SeekableReadStream &twoda); void readRows2b (Common::SeekableReadStream &twoda); // GDA loading/conversion helpers void load(const GDAFile &gda); void createHeaderMap(); static int32 parseInt(const Common::UString &str); static float parseFloat(const Common::UString &str); friend class TwoDARow; }; } // End of namespace Aurora #endif // AURORA_2DAFILE_H xoreos-tools-0.0.5/src/aurora/archive.cpp000066400000000000000000000035211331663051500204020ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling various archive files. */ #include "src/common/system.h" #include "src/aurora/archive.h" namespace Aurora { Archive::Resource::Resource() : hash(0), type(kFileTypeNone), index(0xFFFFFFFF) { } Archive::Archive() { } Archive::~Archive() { } uint32 Archive::getResourceSize(uint32 UNUSED(index)) const { return 0xFFFFFFFF; } Common::HashAlgo Archive::getNameHashAlgo() const { return Common::kHashNone; } uint32 Archive::findResource(uint64 hash) const { if (getNameHashAlgo() == Common::kHashNone) return 0xFFFFFFFF; for (ResourceList::const_iterator r = getResources().begin(); r != getResources().end(); ++r) if (r->hash == hash) return r->index; return 0xFFFFFFFF; } uint32 Archive::findResource(const Common::UString &name, FileType type) const { for (ResourceList::const_iterator r = getResources().begin(); r != getResources().end(); ++r) if ((r->type == type) && (r->name == name)) return r->index; return 0xFFFFFFFF; } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/archive.h000066400000000000000000000052061331663051500200510ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling various archive files. */ #ifndef AURORA_ARCHIVE_H #define AURORA_ARCHIVE_H #include #include #include "src/common/types.h" #include "src/common/ustring.h" #include "src/common/hash.h" #include "src/aurora/types.h" namespace Common { class SeekableReadStream; } namespace Aurora { /** An abstract file archive. */ class Archive : boost::noncopyable { public: /** A resource within the archive. */ struct Resource { Common::UString name; ///< The resource's name. uint64 hash; ///< The resource's hashed name. FileType type; ///< The resource's type. uint32 index; ///< The resource's local index within the archive. Resource(); }; typedef std::list ResourceList; Archive(); virtual ~Archive(); /** Return the list of resources. */ virtual const ResourceList &getResources() const = 0; /** Return the size of a resource. */ virtual uint32 getResourceSize(uint32 index) const; /** Return a stream of the resource's contents. * * @param index The index of the resource we want. * @param tryNoCopy Try to return a SeekableSubReadStream of the archive instead of copying. * @return A (sub)stream of the resource's contents. */ virtual Common::SeekableReadStream *getResource(uint32 index, bool tryNoCopy = false) const = 0; /** Return with which algorithm the name is hashed. */ virtual Common::HashAlgo getNameHashAlgo() const; /** Return the index of the resource matching the hash, or 0xFFFFFFFF if not found. */ uint32 findResource(uint64 hash) const; /** Return the index of the resource matching the name and type, or 0xFFFFFFFF if not found. */ uint32 findResource(const Common::UString &name, FileType type) const; }; } // End of namespace Aurora #endif // AURORA_ARCHIVE_H xoreos-tools-0.0.5/src/aurora/aurorafile.cpp000066400000000000000000000046731331663051500211230ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Base for BioWare's Aurora engine files. */ #include "src/common/readstream.h" #include "src/aurora/aurorafile.h" namespace Aurora { AuroraFile::AuroraFile() { clear(); } void AuroraFile::clear() { _id = 0; _version = 0; _utf16le = false; } uint32 AuroraFile::getID() const { return _id; } uint32 AuroraFile::getVersion() const { return _version; } bool AuroraFile::isUTF16LE() const { return _utf16le; } void AuroraFile::readHeader(Common::ReadStream &stream, uint32 &id, uint32 &version, bool &utf16le) { id = stream.readUint32BE(); version = stream.readUint32BE(); if (((id & 0x00FF00FF) == 0) && ((version & 0x00FF00FF) == 0)) { // There's 0-bytes in the ID and version, this looks like little-endian UTF-16 utf16le = true; id = convertUTF16LE(id, version); uint32 version1 = stream.readUint32BE(); uint32 version2 = stream.readUint32BE(); version = convertUTF16LE(version1, version2); } else utf16le = false; } void AuroraFile::readHeader(Common::ReadStream &stream, uint32 &id, uint32 &version) { bool utf16le; readHeader(stream, id, version, utf16le); } uint32 AuroraFile::readHeaderID(Common::ReadStream &stream) { uint32 id, version; readHeader(stream, id, version); return id; } void AuroraFile::readHeader(Common::ReadStream &stream) { readHeader(stream, _id, _version, _utf16le); } uint32 AuroraFile::convertUTF16LE(uint32 x1, uint32 x2) { // Take 8 byte and remove every second byte return ((x1 & 0xFF000000) ) | ((x1 & 0x0000FF00) << 8) | ((x2 & 0xFF000000) >> 16) | ((x2 & 0x0000FF00) >> 8); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/aurorafile.h000066400000000000000000000055001331663051500205560ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Base for BioWare's Aurora engine files. */ #ifndef AURORA_AURORAFILE_H #define AURORA_AURORAFILE_H #include "src/common/types.h" namespace Common { class ReadStream; } namespace Aurora { /** Base class for most files found in games using BioWare's Aurora engine. * * Aurora files generally start with a 4-byte human-readable ID, for example * 'ERF ', followed by a 4-byte version string, like 'V1.0'. This base class * reads them as big-endian 32-bit integer values. See the MKTAG() macro, as * defined in src/common/endianness.h, for generating values to compare the * IDs read out of a stream against. * * Later games encode these ID and version values as 8-byte, little-endian * UTF-16 strings instead. We automatically detect this, convert them back * into the old format, and set a flag that can be queried with the method * isUTF16LE(). * * Alternatively, AuroraFile provides static methods for reading the base * header out of a stream. */ class AuroraFile { public: AuroraFile(); void clear(); /** Return the file's ID. */ uint32 getID() const; /** Return the file's version. */ uint32 getVersion() const; /** Were the ID and version encoded in little-endian UTF-16 in the file? */ bool isUTF16LE() const; // .--- Static base header readers /** Read the header out of a stream. */ static void readHeader(Common::ReadStream &stream, uint32 &id, uint32 &version, bool &utf16le); /** Read the ID and version out of a stream. */ static void readHeader(Common::ReadStream &stream, uint32 &id, uint32 &version); /** Read the ID out of a stream. */ static uint32 readHeaderID(Common::ReadStream &stream); // '--- protected: uint32 _id; ///< The file's ID. uint32 _version; ///< The file's version. bool _utf16le; ///< The file's ID and version are in little-endian UTF-16. void readHeader(Common::ReadStream &stream); static uint32 convertUTF16LE(uint32 x1, uint32 x2); }; } // End of namespace Aurora #endif // AURORA_AURORAFILE_H xoreos-tools-0.0.5/src/aurora/biffile.cpp000066400000000000000000000104561331663051500203660ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's BIFs (resource data files). */ /* See BioWare's own specs released for Neverwinter Nights modding * () */ #include #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/error.h" #include "src/common/memreadstream.h" #include "src/aurora/biffile.h" #include "src/aurora/keyfile.h" static const uint32 kBIFID = MKTAG('B', 'I', 'F', 'F'); static const uint32 kVersion1 = MKTAG('V', '1', ' ', ' '); static const uint32 kVersion11 = MKTAG('V', '1', '.', '1'); namespace Aurora { BIFFile::BIFFile(Common::SeekableReadStream *bif) : _bif(bif) { assert(_bif); load(*_bif); } BIFFile::~BIFFile() { } void BIFFile::load(Common::SeekableReadStream &bif) { readHeader(bif); if (_id != kBIFID) throw Common::Exception("Not a BIF file (%s)", Common::debugTag(_id).c_str()); if ((_version != kVersion1) && (_version != kVersion11)) throw Common::Exception("Unsupported BIF file version %s", Common::debugTag(_version).c_str()); uint32 varResCount = bif.readUint32LE(); uint32 fixResCount = bif.readUint32LE(); if (fixResCount != 0) throw Common::Exception("TODO: Fixed BIF resources"); _iResources.resize(varResCount); uint32 offVarResTable = bif.readUint32LE(); try { readVarResTable(bif, offVarResTable); } catch (Common::Exception &e) { e.add("Failed reading BIF file"); throw; } } void BIFFile::readVarResTable(Common::SeekableReadStream &bif, uint32 offset) { bif.seek(offset); for (IResourceList::iterator res = _iResources.begin(); res != _iResources.end(); ++res) { bif.skip(4); // ID if (_version == kVersion11) bif.skip(4); // Flags res->offset = bif.readUint32LE(); res->size = bif.readUint32LE(); res->type = (FileType) bif.readUint32LE(); } } void BIFFile::mergeKEY(const KEYFile &key, uint32 bifIndex) { const KEYFile::ResourceList &keyResList = key.getResources(); for (KEYFile::ResourceList::const_iterator keyRes = keyResList.begin(); keyRes != keyResList.end(); ++keyRes) { if (keyRes->bifIndex != bifIndex) continue; if (keyRes->resIndex >= _iResources.size()) { warning("Resource index out of range (%d/%d)", keyRes->resIndex, (int) _iResources.size()); continue; } if (keyRes->type != _iResources[keyRes->resIndex].type) warning("KEY and BIF disagree on the type of the resource \"%s\" (%d, %d). Trusting the BIF", keyRes->name.c_str(), keyRes->type, _iResources[keyRes->resIndex].type); Resource res; res.name = keyRes->name; res.type = _iResources[keyRes->resIndex].type; res.index = keyRes->resIndex; _resources.push_back(res); } } uint32 BIFFile::getInternalResourceCount() const { return _iResources.size(); } const Archive::ResourceList &BIFFile::getResources() const { return _resources; } const BIFFile::IResource &BIFFile::getIResource(uint32 index) const { if (index >= _iResources.size()) throw Common::Exception("Resource index out of range (%u/%u)", index, (uint)_iResources.size()); return _iResources[index]; } uint32 BIFFile::getResourceSize(uint32 index) const { return getIResource(index).size; } Common::SeekableReadStream *BIFFile::getResource(uint32 index, bool tryNoCopy) const { const IResource &res = getIResource(index); if (tryNoCopy) return new Common::SeekableSubReadStream(_bif.get(), res.offset, res.offset + res.size); _bif->seek(res.offset); return _bif->readStream(res.size); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/biffile.h000066400000000000000000000073301331663051500200300ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's BIFs (resource data files). */ #ifndef AURORA_BIFFILE_H #define AURORA_BIFFILE_H #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/aurora/types.h" #include "src/aurora/archive.h" #include "src/aurora/aurorafile.h" namespace Common { class SeekableReadStream; } namespace Aurora { class KEYFile; /** Class to hold resource data information of a BIF file. * * A BIF file is one part of the KEY/BIF resource archive system. * The KEY file contains the resource names and types, and the BIF * file contains the actual resource data. So BIF files only contain * the resource data itself. * * A KEY file can index resources of several BIF files and several * BIF files can in turn index different resources of the same BIF * file. * * See also classes KEYFile in keyfile.h. * * There are two versions of BIF files known and supported * - V1, used by Neverwinter Nights, Neverwinter Nights 2, Knight of * the Old Republic, Knight of the Old Republic II and Jade Empire * - V1.1, used by The Witcher * * Please note that BIF (and KEY) files found in Infinity Engine * games (Baldur's Gate et al) are not supported at all, even though * they claim to be V1. */ class BIFFile : public Archive, public AuroraFile { public: /** Take over this stream and read a BIF file out of it. */ BIFFile(Common::SeekableReadStream *bif); ~BIFFile(); /** Return the number of internal resources (including unmerged ones). */ uint32 getInternalResourceCount() const; /** Return the list of resources. */ const ResourceList &getResources() const; /** Return the size of a resource. */ uint32 getResourceSize(uint32 index) const; /** Return a stream of the resource's contents. */ Common::SeekableReadStream *getResource(uint32 index, bool tryNoCopy = false) const; /** Merge information from the KEY into the BIF. * * Without this step, this BIFFile archive does not contain any * resource names at all. * * @param key A KEYFile with information about this BIF. * @param bifIndex The index this BIF has within the KEY file. */ void mergeKEY(const KEYFile &key, uint32 bifIndex); private: /** Internal resource information. */ struct IResource { FileType type; ///< The resource's type. uint32 offset; ///< The offset of the resource within the BIF. uint32 size; ///< The resource's size. }; typedef std::vector IResourceList; Common::ScopedPtr _bif; /** External list of resource names and types. */ ResourceList _resources; /** Internal list of resource offsets and sizes. */ IResourceList _iResources; void load(Common::SeekableReadStream &bif); void readVarResTable(Common::SeekableReadStream &bif, uint32 offset); const IResource &getIResource(uint32 index) const; }; } // End of namespace Aurora #endif // AURORA_BIFFILE_H xoreos-tools-0.0.5/src/aurora/erffile.cpp000066400000000000000000000630331331663051500204010ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's ERFs (encapsulated resource file). */ /* See BioWare's own specs released for Neverwinter Nights modding * () */ #include #include "src/common/memreadstream.h" #include "src/common/readfile.h" #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/error.h" #include "src/common/encoding.h" #include "src/common/md5.h" #include "src/common/blowfish.h" #include "src/common/deflate.h" #include "src/aurora/erffile.h" #include "src/aurora/util.h" static const uint32 kERFID = MKTAG('E', 'R', 'F', ' '); static const uint32 kMODID = MKTAG('M', 'O', 'D', ' '); static const uint32 kHAKID = MKTAG('H', 'A', 'K', ' '); static const uint32 kSAVID = MKTAG('S', 'A', 'V', ' '); static const uint32 kVersion10 = MKTAG('V', '1', '.', '0'); static const uint32 kVersion11 = MKTAG('V', '1', '.', '1'); static const uint32 kVersion20 = MKTAG('V', '2', '.', '0'); static const uint32 kVersion22 = MKTAG('V', '2', '.', '2'); static const uint32 kVersion30 = MKTAG('V', '3', '.', '0'); namespace Aurora { static const size_t kNWNPremiumKeyLength = 56; static const byte kNWNPremiumKeys[][kNWNPremiumKeyLength] = { { 0x8A, 0x83, 0x5A, 0x2D, 0x01, 0x10, 0x5C, 0xBE, 0xCE, 0x2C, 0xD0, 0x69, 0xB8, 0x48, 0xC9, 0xBE, 0xAA, 0x7E, 0x57, 0xBD, 0xAB, 0x94, 0xCE, 0x0D, 0x09, 0x10, 0xBD, 0x57, 0x8D, 0x1A, 0x0D, 0x35, 0xC9, 0x84, 0x90, 0xFA, 0x7B, 0x65, 0x32, 0x97, 0xCF, 0x39, 0x66, 0xA7, 0x60, 0xEC, 0x99, 0xEF, 0x76, 0x5A, 0x3B, 0x2C, 0x2F, 0x0A, 0x24, 0xC3 }, { 0x5C, 0xA8, 0x83, 0xCE, 0x6D, 0x9C, 0x84, 0x3B, 0xDE, 0xA1, 0xD7, 0x85, 0x78, 0x87, 0xFD, 0x0D, 0xD7, 0x97, 0x42, 0x38, 0x93, 0x53, 0xCD, 0x3D, 0xEC, 0x03, 0xCE, 0x15, 0x09, 0x48, 0xD7, 0x9B, 0x86, 0x20, 0x19, 0x21, 0xC2, 0x6E, 0x42, 0xEE, 0xAF, 0xBE, 0xCA, 0x41, 0xBF, 0x0A, 0x66, 0x9A, 0x2A, 0x8F, 0xC2, 0x04, 0x56, 0x14, 0x77, 0x82 }, { 0x94, 0x37, 0xDD, 0x56, 0xED, 0xD9, 0xF0, 0x41, 0x91, 0x28, 0xC2, 0xD5, 0x4F, 0x97, 0xE8, 0x5D, 0x95, 0x42, 0x41, 0xB5, 0xA3, 0xA2, 0x03, 0xB6, 0x08, 0x8B, 0xC1, 0xC7, 0xCB, 0xEE, 0xD8, 0xD9, 0x83, 0x4E, 0x9F, 0xAB, 0x69, 0x41, 0x6C, 0xFC, 0x87, 0x13, 0xB5, 0xFD, 0xCA, 0x0A, 0x1D, 0x83, 0x89, 0x51, 0x4E, 0xF3, 0x5B, 0xED, 0x9A, 0x5C }, { 0xEC, 0xBF, 0x9A, 0x75, 0x39, 0xE4, 0x65, 0x10, 0xCA, 0xA1, 0xB6, 0x3A, 0x76, 0xA2, 0x50, 0xDD, 0xE2, 0x06, 0xEA, 0x39, 0x20, 0x0F, 0xBC, 0xC7, 0x5D, 0x03, 0xD6, 0xB2, 0x75, 0x83, 0xEF, 0x08, 0xA7, 0xFD, 0x68, 0xDB, 0x33, 0xAA, 0x69, 0xA1, 0x39, 0x80, 0x62, 0x29, 0x8C, 0xE9, 0x2B, 0xA9, 0x60, 0xC6, 0x93, 0x27, 0x2C, 0x0D, 0x42, 0x26 }, { 0x72, 0xA3, 0x8B, 0x0C, 0x49, 0x63, 0x53, 0x32, 0x7D, 0x86, 0x9C, 0x3D, 0x48, 0x84, 0x77, 0xBD, 0xBB, 0x7C, 0x48, 0xDC, 0x33, 0x45, 0x40, 0x78, 0xAF, 0x26, 0x64, 0x96, 0x7F, 0x80, 0x44, 0x67, 0xF7, 0xDA, 0x08, 0x74, 0xF4, 0xD8, 0x7C, 0x2D, 0x2D, 0x1F, 0xF2, 0xD1, 0x5D, 0x18, 0xF7, 0xD2, 0x71, 0x28, 0xD0, 0x31, 0x5C, 0xCC, 0x6E, 0xCD }, { 0x1D, 0xEA, 0x5E, 0x04, 0x0B, 0x43, 0xF2, 0x2F, 0x23, 0x90, 0x04, 0x38, 0x5C, 0xA1, 0x18, 0x9C, 0xFF, 0xB1, 0xB1, 0x86, 0xE6, 0x69, 0x67, 0x8E, 0x29, 0x08, 0x94, 0x4C, 0x08, 0x22, 0x0A, 0x8C, 0x9D, 0xC5, 0xFE, 0xE2, 0x27, 0x84, 0xE7, 0xD3, 0xD1, 0x6B, 0xF2, 0x38, 0xF4, 0xFF, 0xBF, 0x80, 0x7E, 0x1E, 0x98, 0x75, 0x32, 0xA3, 0x2C, 0xF6 } }; ERFFile::ERFHeader::ERFHeader() { clear(); } ERFFile::ERFHeader::~ERFHeader() { } void ERFFile::ERFHeader::clear() { resCount = 0; langCount = 0; descriptionID = 0; offDescription = 0xFFFFFFFF; offKeyList = 0xFFFFFFFF; offResList = 0xFFFFFFFF; descriptionSize = 0; buildYear = 0; buildDay = 0; isNWNPremium = false; moduleID = 0; encryption = kEncryptionNone; compression = kCompressionNone; clearStringTable(); } void ERFFile::ERFHeader::clearStringTable() { stringTable.reset(); stringTableSize = 0; } bool ERFFile::ERFHeader::isSensible(size_t fileSize) { if ((buildYear > 2200) || (buildYear < 2000) || (buildDay > 366)) return false; if ((resCount >= 131072) || (langCount > 32)) return false; if ((offDescription != 0xFFFFFFFF) && (offDescription > fileSize)) return false; if ((offKeyList != 0xFFFFFFFF) && (offKeyList > fileSize)) return false; if ((offResList != 0xFFFFFFFF) && (offResList > fileSize)) return false; return true; } ERFFile::ERFFile(Common::SeekableReadStream *erf, const std::vector &password) : _erf(erf), _password(password) { assert(_erf); load(); } ERFFile::~ERFFile() { } void ERFFile::verifyVersion(uint32 id, uint32 version, bool utf16le) { if ((id != kERFID) && (id != kMODID) && (id != kHAKID) && (id != kSAVID)) throw Common::Exception("Not an ERF file (%s)", Common::debugTag(id).c_str()); if ((version != kVersion10) && (version != kVersion11) && (version != kVersion20) && (version != kVersion22) && (version != kVersion30)) throw Common::Exception("Unsupported ERF file version %s", Common::debugTag(version).c_str()); if ((version != kVersion10) && (version != kVersion11) && !utf16le) throw Common::Exception("ERF file version 2.0+, but not UTF-16LE"); } void ERFFile::verifyPasswordDigest() { if ((_header.encryption == kEncryptionNone) || (_header.encryption == kEncryptionBlowfishNWN)) return; if (_password.empty()) throw Common::Exception("Encrypted; password required"); if (_header.encryption == kEncryptionXOR) throw Common::Exception("Unsupported XOR encryption"); if (_header.encryption == kEncryptionBlowfishDAO) { // The digest is the simple MD5 sum of the password if (!Common::compareMD5Digest(_password, _header.passwordDigest)) throw Common::Exception("Password digest does not match"); // Parse the password into a number, and create an 8-byte little endian array out of it Common::UString passwordString(reinterpret_cast(&_password[0]), _password.size()); uint64 passwordNumber = 0; Common::parseString(passwordString, passwordNumber); _password.resize(8); for (size_t i = 0; i < 8; i++) { _password[i] = passwordNumber & 0xFF; passwordNumber >>= 8; } return; } if (_header.encryption == kEncryptionBlowfishDA2) { // The digest is the MD5 sum of an [0-255] array encrypted by the password byte buffer[256]; for (size_t i = 0; i < sizeof(buffer); i++) buffer[i] = i; Common::MemoryReadStream bufferStream(buffer); Common::ScopedPtr bufferEncrypted(Common::encryptBlowfishEBC(bufferStream, _password)); if (!Common::compareMD5Digest(*bufferEncrypted, _header.passwordDigest)) throw Common::Exception("Password digest does not match"); return; } throw Common::Exception("Invalid encryption type %u", (uint)_header.encryption); } bool ERFFile::decryptNWNPremiumHeader(Common::SeekableReadStream &erf, ERFHeader &header, const std::vector &password) { Common::ScopedPtr decryptERF(decrypt(erf, erf.pos(), 152, kEncryptionBlowfishNWN, password)); readV11Header(*decryptERF, header); return header.isSensible(erf.size()); } bool ERFFile::findNWNPremiumKey(Common::SeekableReadStream &erf, ERFHeader &header, const std::vector &md5, std::vector &password) { assert(md5.empty() || (md5.size() == Common::kMD5Length)); password.resize(kNWNPremiumKeyLength); const size_t headerPos = erf.pos(); for (size_t i = 0; i < ARRAYSIZE(kNWNPremiumKeys); i++) { std::memcpy(&password[0], kNWNPremiumKeys[i], kNWNPremiumKeyLength); if (!md5.empty()) std::memcpy(&password[0] + kNWNPremiumKeyLength - Common::kMD5Length, &md5[0], Common::kMD5Length); erf.seek(headerPos); if (decryptNWNPremiumHeader(erf, header, password)) return true; } return false; } void ERFFile::readNWNPremiumHeader(Common::SeekableReadStream &erf, ERFHeader &header, std::vector &password) { assert(header.encryption == kEncryptionBlowfishNWN); if (!password.empty() && (password.size() != Common::kMD5Length)) throw Common::Exception("Invalid Neverwinter Nights premium module MD5 length (%u)", (uint)password.size()); const std::vector md5 = password; if (!findNWNPremiumKey(erf, header, md5, password)) throw Common::Exception("Wrong Neverwinter Nights premium module key"); header.isNWNPremium = true; header.encryption = kEncryptionBlowfishNWN; } void ERFFile::load() { readHeader(*_erf); verifyVersion(_id, _version, _utf16le); try { readERFHeader(*_erf, _header, _version, _password); verifyPasswordDigest(); readDescription(_description, *_erf, _header); if (_header.encryption == kEncryptionBlowfishNWN) decryptNWNPremium(); readResources(*_erf, _header); _header.clearStringTable(); } catch (Common::Exception &e) { e.add("Failed reading ERF file"); throw; } } void ERFFile::decryptNWNPremium() { assert(_header.encryption == kEncryptionBlowfishNWN); _erf->seek(0); _erf.reset(decrypt(*_erf, kEncryptionBlowfishNWN, _password)); _header.encryption = kEncryptionNone; } void ERFFile::readV10Header(Common::SeekableReadStream &erf, ERFHeader &header) { header.langCount = erf.readUint32LE(); // Number of languages for the description header.descriptionSize = erf.readUint32LE(); // Number of bytes in the description header.resCount = erf.readUint32LE(); // Number of resources in the ERF header.offDescription = erf.readUint32LE(); header.offKeyList = erf.readUint32LE(); header.offResList = erf.readUint32LE(); header.buildYear = erf.readUint32LE() + 1900; header.buildDay = erf.readUint32LE(); header.descriptionID = erf.readUint32LE(); erf.skip(116); // Reserved } void ERFFile::readV11Header(Common::SeekableReadStream &erf, ERFHeader &header) { header.langCount = erf.readUint32LE(); // Number of languages for the description header.descriptionSize = erf.readUint32LE(); // Number of bytes in the description header.resCount = erf.readUint32LE(); // Number of resources in the ERF header.offDescription = erf.readUint32LE(); header.offKeyList = erf.readUint32LE(); header.offResList = erf.readUint32LE(); header.buildYear = erf.readUint32LE() + 1900; header.buildDay = erf.readUint32LE(); header.descriptionID = erf.readUint32LE(); erf.skip(116); // Reserved const uint32 keyListSize = header.offResList - header.offKeyList; /* Check whether the "true" V1.1 extended filenames would fit into the key * list. If so, this is probably a true V1.1 ERF, as found in Neverwinter * Nights 2. If not, this is a Neverwinter Nights premium module with shorter * filenames. */ header.isNWNPremium = (header.resCount > 0) && ((keyListSize / header.resCount) < 40); if (!header.isSensible()) { header.isNWNPremium = true; header.encryption = kEncryptionBlowfishNWN; } } void ERFFile::readV20Header(Common::SeekableReadStream &erf, ERFHeader &header) { header.resCount = erf.readUint32LE(); // Number of resources in the ERF header.buildYear = erf.readUint32LE() + 1900; header.buildDay = erf.readUint32LE(); erf.skip(4); // Unknown, always 0xFFFFFFFF? header.offResList = 0x00000020; // Resource list always starts at 0x20 in ERF V2.0 } void ERFFile::readV22Header(Common::SeekableReadStream &erf, ERFHeader &header, uint32 &flags) { header.resCount = erf.readUint32LE(); // Number of resources in the ERF header.buildYear = erf.readUint32LE() + 1900; header.buildDay = erf.readUint32LE(); erf.skip(4); // Unknown, always 0xFFFFFFFF? flags = erf.readUint32LE(); header.moduleID = erf.readUint32LE(); header.passwordDigest.resize(Common::kMD5Length); if (erf.read(&header.passwordDigest[0], Common::kMD5Length) != Common::kMD5Length) throw Common::Exception(Common::kReadError); header.offResList = 0x00000038; // Resource list always starts at 0x38 in ERF V2.2 header.encryption = (Encryption) ((flags >> 4) & 0x0000000F); header.compression = (Compression) ((flags >> 29) & 0x00000007); } void ERFFile::readV30Header(Common::SeekableReadStream &erf, ERFHeader &header, uint32 &flags) { header.stringTableSize = erf.readUint32LE(); // Number of bytes in the string table header.resCount = erf.readUint32LE(); // Number of resources in the ERF flags = erf.readUint32LE(); header.moduleID = erf.readUint32LE(); header.passwordDigest.resize(Common::kMD5Length); if (erf.read(&header.passwordDigest[0], Common::kMD5Length) != Common::kMD5Length) throw Common::Exception(Common::kReadError); header.stringTable.reset(new char[header.stringTableSize]); if (erf.read(header.stringTable.get(), header.stringTableSize) != header.stringTableSize) { header.clearStringTable(); throw Common::Exception("Failed to read ERF string table"); } // Resource list always starts after the string table in ERF V3.0 header.offResList = 0x00000030 + header.stringTableSize; header.encryption = (Encryption) ((flags >> 4) & 0x0000000F); header.compression = (Compression) ((flags >> 29) & 0x00000007); } void ERFFile::readERFHeader(Common::SeekableReadStream &erf, ERFHeader &header, uint32 version, std::vector &password) { header.clear(); if (version == kVersion10) { /* Version 1.0: * Neverwinter Nights, Knights of the Old Republic I and II, * Jade Empire, The Witcher. */ readV10Header(erf, header); } else if (version == kVersion11) { /* Version 1.1: * There's two slightly different formats of the 1.1 ERF version: * - The one is present in Neverwinter Nights 2. It extends the filename * field in the key list to 32 characters (from 16 in V1.0) * - Premium modules in Neverwinter Nights. They are identical to V1.0 * ERFs, except that they may be encrypted. */ const size_t headerPos = erf.pos(); readV11Header(erf, header); if (header.encryption == kEncryptionBlowfishNWN) { erf.seek(headerPos); readNWNPremiumHeader(erf, header, password); } } else if (version == kVersion20) { /* Version 2.0: * Unencrypted data in Dragon Age: Origins. */ readV20Header(erf, header); } else if (version == kVersion22) { /* Version 2.2: * Encrypted data in Dragon Age: Origins. */ uint32 flags = 0; readV22Header(erf, header, flags); } else if (version == kVersion30) { /* Version 3.0: * Dragon Age II. */ uint32 flags = 0; readV30Header(erf, header, flags); } } void ERFFile::readDescription(LocString &description, Common::SeekableReadStream &erf, const ERFHeader &header) { description.clear(); if ((header.offDescription == 0) || (header.offDescription == 0xFFFFFFFF) || (header.langCount == 0)) return; if (header.encryption == kEncryptionBlowfishNWN) return; erf.seek(header.offDescription); description.readLocString(erf, header.descriptionID, header.langCount); } void ERFFile::readResources(Common::SeekableReadStream &erf, const ERFHeader &header) { _resources.resize(header.resCount); _iResources.resize(header.resCount); if (_version == kVersion10) { readV10KeyList(erf, header); // Read name and type part of the resource list readV10ResList(erf, header); // Read offset and size part of the resource list } else if (_version == kVersion11) { // Read name and type part of the resource list if (header.isNWNPremium) readV10KeyList(erf, header); else readV11KeyList(erf, header); readV10ResList (erf, header); // Read offset and size part of the resource list } else if (_version == kVersion20) { // Read the resource list readV20ResList(erf, header); } else if (_version == kVersion22) { // Read the resource list readV22ResList(erf, header); } else if (_version == kVersion30) { // Read the resource list readV30ResList(erf, header); } } void ERFFile::readV10KeyList(Common::SeekableReadStream &erf, const ERFHeader &header) { erf.seek(header.offKeyList); uint32 index = 0; for (ResourceList::iterator res = _resources.begin(); res != _resources.end(); ++index, ++res) { res->name = Common::readStringFixed(erf, Common::kEncodingASCII, 16); erf.skip(4); // Resource ID res->type = (FileType) erf.readUint16LE(); erf.skip(2); // Reserved res->index = index; } } void ERFFile::readV11KeyList(Common::SeekableReadStream &erf, const ERFHeader &header) { erf.seek(header.offKeyList); uint32 index = 0; for (ResourceList::iterator res = _resources.begin(); res != _resources.end(); ++index, ++res) { res->name = Common::readStringFixed(erf, Common::kEncodingASCII, 32); erf.skip(4); // Resource ID res->type = (FileType) erf.readUint16LE(); erf.skip(2); // Reserved res->index = index; } } void ERFFile::readV10ResList(Common::SeekableReadStream &erf, const ERFHeader &header) { erf.seek(header.offResList); for (IResourceList::iterator res = _iResources.begin(); res != _iResources.end(); ++res) { res->offset = erf.readUint32LE(); res->packedSize = res->unpackedSize = erf.readUint32LE(); } } void ERFFile::readV20ResList(Common::SeekableReadStream &erf, const ERFHeader &header) { erf.seek(header.offResList); uint32 index = 0; ResourceList::iterator res = _resources.begin(); IResourceList::iterator iRes = _iResources.begin(); for (; (res != _resources.end()) && (iRes != _iResources.end()); ++index, ++res, ++iRes) { Common::UString name = Common::readStringFixed(erf, Common::kEncodingUTF16LE, 64); res->name = TypeMan.setFileType(name, kFileTypeNone); res->type = TypeMan.getFileType(name); res->index = index; iRes->offset = erf.readUint32LE(); iRes->packedSize = iRes->unpackedSize = erf.readUint32LE(); } } void ERFFile::readV22ResList(Common::SeekableReadStream &erf, const ERFHeader &header) { erf.seek(header.offResList); uint32 index = 0; ResourceList::iterator res = _resources.begin(); IResourceList::iterator iRes = _iResources.begin(); for (; (res != _resources.end()) && (iRes != _iResources.end()); ++index, ++res, ++iRes) { Common::UString name = Common::readStringFixed(erf, Common::kEncodingUTF16LE, 64); res->name = TypeMan.setFileType(name, kFileTypeNone); res->type = TypeMan.getFileType(name); res->index = index; iRes->offset = erf.readUint32LE(); iRes->packedSize = erf.readUint32LE(); iRes->unpackedSize = erf.readUint32LE(); } } void ERFFile::readV30ResList(Common::SeekableReadStream &erf, const ERFHeader &header) { erf.seek(header.offResList); uint32 index = 0; ResourceList::iterator res = _resources.begin(); IResourceList::iterator iRes = _iResources.begin(); for (; (res != _resources.end()) && (iRes != _iResources.end()); ++index, ++res, ++iRes) { int32 nameOffset = erf.readSint32LE(); if (nameOffset >= 0) { if ((uint32)nameOffset >= header.stringTableSize) throw Common::Exception("Invalid ERF string table offset"); Common::UString name = header.stringTable.get() + nameOffset; res->name = TypeMan.setFileType(name, kFileTypeNone); res->type = TypeMan.getFileType(name); } res->index = index; res->hash = erf.readUint64LE(); uint32 typeHash = erf.readUint32LE(); // Look up the file type by its hash FileType type = TypeMan.getFileType(Common::kHashFNV32, typeHash); if (type != kFileTypeNone) res->type = type; iRes->offset = erf.readUint32LE(); iRes->packedSize = erf.readUint32LE(); iRes->unpackedSize = erf.readUint32LE(); } } uint32 ERFFile::getBuildYear() const { return _header.buildYear; } uint32 ERFFile::getBuildDay() const { return _header.buildDay; } const LocString &ERFFile::getDescription() const { return _description; } const Archive::ResourceList &ERFFile::getResources() const { return _resources; } const ERFFile::IResource &ERFFile::getIResource(uint32 index) const { if (index >= _iResources.size()) throw Common::Exception("Resource index out of range (%u/%u)", index, (uint)_iResources.size()); return _iResources[index]; } uint32 ERFFile::getResourceSize(uint32 index) const { return getIResource(index).unpackedSize; } Common::SeekableReadStream *ERFFile::getResource(uint32 index, bool tryNoCopy) const { const IResource &res = getIResource(index); if (tryNoCopy && (_header.encryption == kEncryptionNone) && (_header.compression == kCompressionNone)) return new Common::SeekableSubReadStream(_erf.get(), res.offset, res.offset + res.packedSize); _erf->seek(res.offset); // Read Common::MemoryReadStream *stream = _erf->readStream(res.packedSize); // Decrypt if (_header.encryption != kEncryptionNone) stream = decrypt(stream, _header.encryption, _password); // Decompress return decompress(stream, res.unpackedSize); } Common::MemoryReadStream *ERFFile::decrypt(Common::SeekableReadStream &cryptStream, Encryption encryption, const std::vector &password) { switch (encryption) { case kEncryptionBlowfishDAO: case kEncryptionBlowfishDA2: case kEncryptionBlowfishNWN: return Common::decryptBlowfishEBC(cryptStream, password); default: throw Common::Exception("Invalid ERF encryption %u", (uint) encryption); } } Common::MemoryReadStream *ERFFile::decrypt(Common::SeekableReadStream *cryptStream, Encryption encryption, const std::vector &password) { assert(cryptStream); Common::ScopedPtr stream(cryptStream); return decrypt(*stream, encryption, password); } Common::SeekableReadStream *ERFFile::decrypt(Common::SeekableReadStream &erf, size_t pos, size_t size, Encryption encryption, const std::vector &password) { return decrypt(new Common::SeekableSubReadStream(&erf, pos, pos + size), encryption, password); } Common::SeekableReadStream *ERFFile::decrypt(Common::SeekableReadStream &erf, size_t size, Encryption encryption, const std::vector &password) { return decrypt(erf, erf.pos(), size, encryption, password); } Common::SeekableReadStream *ERFFile::decompress(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const { Common::ScopedPtr stream(packedStream); switch (_header.compression) { case kCompressionNone: if (stream->size() == unpackedSize) return stream.release(); return new Common::SeekableSubReadStream(stream.release(), 0, unpackedSize, true); case kCompressionBioWareZlib: return decompressBiowareZlib(stream.release(), unpackedSize); case kCompressionHeaderlessZlib: return decompressHeaderlessZlib(stream.release(), unpackedSize); default: break; } throw Common::Exception("Invalid ERF compression %u", (uint) _header.compression); } Common::SeekableReadStream *ERFFile::decompressBiowareZlib(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const { /* Decompress using raw inflate. An extra one byte header specifies the window size. */ assert(packedStream); Common::ScopedPtr stream(packedStream); const byte * const compressedData = stream->getData(); const uint32 packedSize = stream->size(); return decompressZlib(compressedData + 1, packedSize - 1, unpackedSize, *compressedData >> 4); } Common::SeekableReadStream *ERFFile::decompressHeaderlessZlib(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const { /* Decompress using raw inflate. Use the default maximum window size (15). */ assert(packedStream); Common::ScopedPtr stream(packedStream); const byte * const compressedData = stream->getData(); const uint32 packedSize = stream->size(); return decompressZlib(compressedData, packedSize, unpackedSize, Common::kWindowBitsMax); } Common::SeekableReadStream *ERFFile::decompressZlib(const byte *compressedData, uint32 packedSize, uint32 unpackedSize, int windowBits) const { // Decompress. Negative window size to signal not to look for a gzip header. const byte *data = Common::decompressDeflate(compressedData, packedSize, unpackedSize, -windowBits); return new Common::MemoryReadStream(data, unpackedSize, true); } Common::HashAlgo ERFFile::getNameHashAlgo() const { // Only V3 uses hashing return (_version == kVersion30) ? Common::kHashFNV64 : Common::kHashNone; } LocString ERFFile::getDescription(Common::SeekableReadStream &erf) { uint32 id, version; bool ut16le; readHeader(erf, id, version, ut16le); verifyVersion(id, version, ut16le); ERFHeader header; LocString description; try { std::vector password; readERFHeader(erf, header, version, password); } catch (...) { return description; } readDescription(description, erf, header); return description; } LocString ERFFile::getDescription(const Common::UString &fileName) { Common::ReadFile erf(fileName); return getDescription(erf); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/erffile.h000066400000000000000000000262321331663051500200460ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's ERFs (encapsulated resource file). */ #ifndef AURORA_ERFFILE_H #define AURORA_ERFFILE_H #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/ustring.h" #include "src/aurora/types.h" #include "src/aurora/archive.h" #include "src/aurora/aurorafile.h" #include "src/aurora/locstring.h" namespace Common { class SeekableReadStream; } namespace Aurora { /** Class to hold resource data of an ERF archive file. * * The ERF file is, together with KEY and BIF files, the most basic * and widespread archive archive format used in Aurora engine games. * There are several versions with different features. * * Supported versions: * - 1.0: * - Used in Neverwinter Nights, Knights of the Old Republic I and II, * Jade Empire and The Witcher * - 16 ASCII characters per resource name * - Extension saved as a Type ID * - Includes a localized description text field * - 1.1 (variant a): * - Used in BioWare premium modules for Neverwinter Nights * - Blowfish encrypted * - Otherwise, identical to the 1.0 format * - 1.1 (variant b): * - Used in Neverwinter Nights 2 * - 32 ASCII characters per resource name * - Extension saved as a Type ID * - Includes a localized description text field * - 2.0: * - Used in Dragon Age: Origins * - 32 UTF-16 characters per resource name * - Resource name includes extension and path * - 2.2: * - Used in Dragon Age: Origins * - Optionally Blowfish encrypted * - Optionally DEFLATE compressed * - Otherwise, identical to the 2.0 format * - 3.0: * - Dragon Age II * - Optionally Blowfish encrypted * - Optionally DEFLATE compressed * - Variable amount of ASCII characters per resource name * - Resource name includes extension and path * - Optionally, resource names are stripped in favour of a FNV64 * hash of the resource name (including path and extension) and * a FNV32 hash of only the extension * * Known unsupported features: * - XOR encryption as used in versions 2.2 and 3.0 * * ERF files can have several different file extensions: * - .erf: Generic resource archive * - .nwm: BioWare original campaign modules * - .mod: Community adventure modules * - .hak: Additional, shared module resources * - .sav: Save games * - .crf: Creature resources * - .rim: Room resources in the Dragon Age games (Note: in earlier games, * .rim are RIM files. See also class RIMFile in rimfile.h.) * - .rimp: Patch resources */ class ERFFile : public Archive, public AuroraFile { public: /** Take over this stream and read an ERF file out of it. * * When the ERF is encrypted, use this password to decrypt it. * * In Dragon Age: Origins and Dragon Age II, each DLC can have a unique * password with which many of the DLC's ERF archive are encrypted. This * password is used to directly decrypt the archive. * * In Neverwinter Nights, each premium module consists of an unencrypted * .nwm file and an encrypted .hak file, both of which are ERF archives. * In this case, the password is the MD5 of the .nwm file. It is then used * to calculate the key to decrypt the .hak file. */ ERFFile(Common::SeekableReadStream *erf, const std::vector &password = std::vector()); ~ERFFile(); /** Return the list of resources. */ const ResourceList &getResources() const; /** Return the size of a resource. */ uint32 getResourceSize(uint32 index) const; /** Return a stream of the resource's contents. */ Common::SeekableReadStream *getResource(uint32 index, bool tryNoCopy = false) const; /** Return the year the ERF was built. */ uint32 getBuildYear() const; /** Return the day of year the ERF was built. */ uint32 getBuildDay() const; /** Return the description. */ const LocString &getDescription() const; /** Return with which algorithm the name is hashed. */ Common::HashAlgo getNameHashAlgo() const; static LocString getDescription(Common::SeekableReadStream &erf); static LocString getDescription(const Common::UString &fileName); private: enum Encryption { kEncryptionNone = 0, ///< No encryption at all. kEncryptionXOR = 1, ///< XOR encryption as used by V2.2 and V3.0 (UNSUPPORTED!) kEncryptionBlowfishDAO = 2, ///< Blowfish encryption as used by Dragon Age: Origins (V2.2). kEncryptionBlowfishDA2 = 3, ///< Blowfish encryption as used by Dragon Age II (V3.0). kEncryptionBlowfishNWN = 16 ///< Blowfish encryption as used by Neverwinter Nights (V1.1). }; enum Compression { kCompressionNone = 0, ///< No compression as all. kCompressionBioWareZlib = 1, ///< Compression using DEFLATE with an extra header byte. kCompressionHeaderlessZlib = 7 ///< Compression using DEFLATE with default parameters. }; /** The header of an ERF file. */ struct ERFHeader { uint32 resCount; ///< Number of resources in this ERF. uint32 langCount; ///< Number of language strings in the description. uint32 descriptionID; ///< ID of the description. uint32 offDescription; ///< Offset to the description. uint32 offKeyList; ///< Offset to the key list. uint32 offResList; ///< Offset to the resource list. uint32 descriptionSize; ///< Number of bytes in the description structure. uint32 buildYear; ///< The year the ERF was built. uint32 buildDay; ///< The day of year the ERF was built. bool isNWNPremium; ///< Is this a Neverwinter Nights premium module? Common::ScopedArray stringTable; ///< String table used for hashed ERFs. uint32 stringTableSize; ///< Size of the string table. uint32 moduleID; ///< ID of the module this ERF belongs to. Encryption encryption; ///< The encryption algorithm in use. Compression compression; ///< The compression algorithm in use. /** Digest of the encryption password, if any. */ std::vector passwordDigest; ERFHeader(); ~ERFHeader(); void clear(); void clearStringTable(); bool isSensible(size_t fileSize = SIZE_MAX); }; /** Internal resource information. */ struct IResource { uint32 offset; ///< The offset of the resource within the ERF. uint32 packedSize; ///< The resource's packed size. uint32 unpackedSize; ///< The resource's unpacked size. }; typedef std::vector IResourceList; Common::ScopedPtr _erf; ERFHeader _header; /** The ERF's description. */ LocString _description; /** External list of resource names and types. */ ResourceList _resources; /** Internal list of resource offsets and sizes. */ IResourceList _iResources; /** The password we were given, if any. */ std::vector _password; void load(); // .--- Header static void verifyVersion(uint32 id, uint32 version, bool utf16le); static void readERFHeader(Common::SeekableReadStream &erf, ERFHeader &header, uint32 version, std::vector &password); static void readDescription(LocString &description, Common::SeekableReadStream &erf, const ERFHeader &header); void readResources(Common::SeekableReadStream &erf, const ERFHeader &header); // '--- // .--- V1.0 static void readV10Header(Common::SeekableReadStream &erf, ERFHeader &header); void readV10ResList(Common::SeekableReadStream &erf, const ERFHeader &header); void readV10KeyList(Common::SeekableReadStream &erf, const ERFHeader &header); // '--- // .--- V1.1 static void readV11Header(Common::SeekableReadStream &erf, ERFHeader &header); void readV11KeyList(Common::SeekableReadStream &erf, const ERFHeader &header); // '--- // .--- V2.0 static void readV20Header(Common::SeekableReadStream &erf, ERFHeader &header); void readV20ResList(Common::SeekableReadStream &erf, const ERFHeader &header); // '--- // .--- V2.2 static void readV22Header(Common::SeekableReadStream &erf, ERFHeader &header, uint32 &flags); void readV22ResList(Common::SeekableReadStream &erf, const ERFHeader &header); // '--- // .--- V3.0 static void readV30Header(Common::SeekableReadStream &erf, ERFHeader &header, uint32 &flags); void readV30ResList(Common::SeekableReadStream &erf, const ERFHeader &header); // '--- // .--- Encryption void verifyPasswordDigest(); static Common::MemoryReadStream *decrypt(Common::SeekableReadStream &cryptStream, Encryption encryption, const std::vector &password); static Common::MemoryReadStream *decrypt(Common::SeekableReadStream *cryptStream, Encryption encryption, const std::vector &password); static Common::SeekableReadStream *decrypt(Common::SeekableReadStream &erf, size_t pos, size_t size, Encryption encryption, const std::vector &password); static Common::SeekableReadStream *decrypt(Common::SeekableReadStream &erf, size_t size, Encryption encryption, const std::vector &password); static bool decryptNWNPremiumHeader(Common::SeekableReadStream &erf, ERFHeader &header, const std::vector &password); static bool findNWNPremiumKey (Common::SeekableReadStream &erf, ERFHeader &header, const std::vector &md5, std::vector &password); static void readNWNPremiumHeader (Common::SeekableReadStream &erf, ERFHeader &header, std::vector &password); void decryptNWNPremium(); // '--- // .--- Compression Common::SeekableReadStream *decompress(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const; Common::SeekableReadStream *decompressBiowareZlib (Common::MemoryReadStream *packedStream, uint32 unpackedSize) const; Common::SeekableReadStream *decompressHeaderlessZlib(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const; Common::SeekableReadStream *decompressZlib(const byte *compressedData, uint32 packedSize, uint32 unpackedSize, int windowBits) const; // '--- const IResource &getIResource(uint32 index) const; }; } // End of namespace Aurora #endif // AURORA_ERFFILE_H xoreos-tools-0.0.5/src/aurora/erfwriter.cpp000066400000000000000000000101471331663051500207740ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Writing BioWare's ERFs (encapsulated resource file). */ #include #include "src/aurora/erfwriter.h" namespace Aurora { static const uint32 kVersion10 = MKTAG('V', '1', '.', '0'); ERFWriter::ERFWriter(uint32 id, uint32 fileCount, Common::SeekableWriteStream &stream, Version version, LocString description) : _stream(stream), _currentFileCount(0), _fileCount(fileCount) { if (version != kERFVersion10) throw Common::Exception("Unsupported ERF version"); stream.writeUint32BE(id); stream.writeUint32BE(kVersion10); // Write Header stream.writeUint32LE(description.getNumStrings()); // Language count stream.writeUint32LE(description.getWrittenSize()); // Localized string size stream.writeUint32LE(_fileCount); // Entry Count // The size of the ERF header, which is immediately followed by the LocString table static const uint32 kLocStringTableOffset = 160; _keyTableOffset = kLocStringTableOffset + description.getWrittenSize(); _resourceTableOffset = _keyTableOffset + _fileCount * 24; stream.writeUint32LE(kLocStringTableOffset); // LocString offset stream.writeUint32LE(_keyTableOffset); // Key List offset stream.writeUint32LE(_resourceTableOffset); // Resource offset // Write the creation time of the file std::time_t now = std::time(0); std::tm *timepoint = std::localtime(&now); stream.writeUint32LE(timepoint->tm_year); stream.writeUint32LE(timepoint->tm_yday); // Write the description string reference if (description.getNumStrings()) stream.writeUint32LE(description.getID()); else stream.writeUint32LE(0); // Write 116 bytes of reserved header data stream.writeZeros(116); // Write the Localized string table description.writeLocString(stream); // Write the empty key list stream.writeZeros(_fileCount * 24); // The offset to the resource table plus the size of the source table _offsetToResourceData = _resourceTableOffset + 8 * _fileCount; // Write the empty resource list stream.writeZeros(8 * _fileCount); } ERFWriter::~ERFWriter() { } void ERFWriter::add(const Common::UString &resRef, FileType resType, Common::ReadStream &stream) { if (_currentFileCount == _fileCount) throw Common::Exception("More files added than expected"); // Write the key table entry _stream.seek(_keyTableOffset + _currentFileCount * 24); // Files without a type are put into ERF archives as the generic RES type if (resType == kFileTypeNone) resType = kFileTypeRES; /* Files with types above this line are not found in ERF archives. * They have no real numerical type ID usable for ERF archives. */ if (resType >= kFileTypeMAXArchive) resType = kFileTypeRES; _stream.write(resRef.c_str(), MIN(resRef.size(), 16)); _stream.writeZeros(16 - MIN(resRef.size(), 16)); _stream.writeUint32LE(_currentFileCount); _stream.writeUint16LE(resType); _stream.writeUint16LE(0); // Unused // Write the actual resource data _stream.seek(_offsetToResourceData); const size_t size = _stream.writeStream(stream); // Write the resource table entry _stream.seek(_resourceTableOffset + _currentFileCount * 8); _stream.writeUint32LE(_offsetToResourceData); _stream.writeUint32LE(size); // Advance data offset and file count _offsetToResourceData += size; _currentFileCount += 1; } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/erfwriter.h000066400000000000000000000042761331663051500204470ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Writing BioWare's ERFs (encapsulated resource file). */ #ifndef AURORA_ERFWRITER_H #define AURORA_ERFWRITER_H #include "src/common/writestream.h" #include "src/common/readstream.h" #include "src/aurora/locstring.h" namespace Aurora { class ERFWriter { public: enum Version { kERFVersion10 // TODO: Add other versions }; /** Create an ERF writer by writing the header to the stream and reserve fileCount * places in the key and resource table. * * @param id The FourCC for the archive. * @param fileCount The number of files which should be contained in the archive. * @param stream The write stream in which the archive should be written. * @param version The ERF version to write * @param description The LocString, that should be used for the description. */ ERFWriter(uint32 id, uint32 fileCount, Common::SeekableWriteStream &stream, Version version = kERFVersion10, LocString description = LocString()); ~ERFWriter(); /** Add a new stream to this archive to be packed. */ void add(const Common::UString &resRef, FileType resType, Common::ReadStream &stream); private: Common::SeekableWriteStream &_stream; uint32 _currentFileCount; uint32 _fileCount; uint32 _offsetToResourceData; uint32 _keyTableOffset; uint32 _resourceTableOffset; }; } // End of namespace Aurora #endif // AURORA_ERFWRITER_H xoreos-tools-0.0.5/src/aurora/gdafile.cpp000066400000000000000000000223631331663051500203610ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's GDAs (2DAs, two-dimensional array, within V4.0 GFFs). */ /* See the GDA description on the Dragon Age toolset wiki * (). */ #include #include "src/common/error.h" #include "src/common/readstream.h" #include "src/common/hash.h" #include "src/common/strutil.h" #include "src/aurora/gdafile.h" #include "src/aurora/gff4file.h" static const uint32 kG2DAID = MKTAG('G', '2', 'D', 'A'); static const uint32 kVersion01 = MKTAG('V', '0', '.', '1'); static const uint32 kVersion02 = MKTAG('V', '0', '.', '2'); namespace Aurora { const size_t GDAFile::kInvalidColumn; const size_t GDAFile::kInvalidRow; GDAFile::GDAFile(Common::SeekableReadStream *gda) : _columns(0), _rowCount(0) { assert(gda); load(gda); } GDAFile::~GDAFile() { } size_t GDAFile::getColumnCount() const { return _columns->size(); } size_t GDAFile::getRowCount() const { return _rowCount; } const GDAFile::Headers &GDAFile::getHeaders() const { return _headers; } bool GDAFile::hasRow(size_t row) const { return getRow(row) != 0; } const GFF4Struct *GDAFile::getRow(size_t row) const { assert(_rowStarts.size() == _rows.size()); /* To find the correct GFF4 for this row, we go through * the list of row start indices in reverse, until we * found one that's not bigger than the row we want. */ for (ptrdiff_t i = _rowStarts.size() - 1; i >= 0; i--) { if (_rowStarts[i] <= row) { row -= _rowStarts[i]; if (row >= _rows[i]->size()) return 0; return (*_rows[i])[row]; } } return 0; } size_t GDAFile::findRow(uint32 id) const { size_t idColumn = findColumn("ID"); if (idColumn == kInvalidColumn) return kInvalidRow; // Go through all rows of all GFF4s, and look for the ID size_t gff4 = 0; for (size_t i = 0, j = 0; i < _rowCount; i++, j++) { if (j >= _rows[gff4]->size()) { if (++gff4 >= _rows.size()) break; j = 0; } if ((*_rows[gff4])[j] && ((*_rows[gff4])[j]->getUint(idColumn) == id)) return i; } return kInvalidRow; } size_t GDAFile::findColumn(const Common::UString &name) const { ColumnNameMap::const_iterator c = _columnNameMap.find(name); if (c != _columnNameMap.end()) return c->second; size_t column = findColumn(Common::hashStringCRC32(name.toLower(), Common::kEncodingUTF16LE)); _columnNameMap[name] = column; return column; } size_t GDAFile::findColumn(uint32 hash) const { ColumnHashMap::const_iterator c = _columnHashMap.find(hash); if (c != _columnHashMap.end()) return c->second; for (size_t i = 0; i < _columns->size(); i++) { if (!(*_columns)[i]) continue; if ((*_columns)[i]->getUint(kGFF4G2DAColumnHash) == hash) { _columnHashMap[hash] = kGFF4G2DAColumn1 + i; return kGFF4G2DAColumn1 + i; } } _columnHashMap[hash] = kInvalidColumn; return kInvalidColumn; } const GFF4Struct *GDAFile::getRowColumn(size_t row, uint32 hash, size_t &column) const { const GFF4Struct *gdaRow = getRow(row); if (!gdaRow || ((column = findColumn(hash)) == kInvalidColumn)) return 0; return gdaRow; } const GFF4Struct *GDAFile::getRowColumn(size_t row, const Common::UString &name, size_t &column) const { const GFF4Struct *gdaRow = getRow(row); if (!gdaRow || ((column = findColumn(name)) == kInvalidColumn)) return 0; return gdaRow; } Common::UString GDAFile::getString(size_t row, uint32 columnHash, const Common::UString &def) const { size_t gdaColumn; const GFF4Struct *gdaRow = getRowColumn(row, columnHash, gdaColumn); if (!gdaRow) return def; return gdaRow->getString(gdaColumn, def); } Common::UString GDAFile::getString(size_t row, const Common::UString &columnName, const Common::UString &def) const { size_t gdaColumn; const GFF4Struct *gdaRow = getRowColumn(row, columnName, gdaColumn); if (!gdaRow) return def; return gdaRow->getString(gdaColumn, def); } int32 GDAFile::getInt(size_t row, uint32 columnHash, int32 def) const { size_t gdaColumn; const GFF4Struct *gdaRow = getRowColumn(row, columnHash, gdaColumn); if (!gdaRow) return def; return gdaRow->getSint(gdaColumn, def); } int32 GDAFile::getInt(size_t row, const Common::UString &columnName, int32 def) const { size_t gdaColumn; const GFF4Struct *gdaRow = getRowColumn(row, columnName, gdaColumn); if (!gdaRow) return def; return gdaRow->getSint(gdaColumn, def); } float GDAFile::getFloat(size_t row, uint32 columnHash, float def) const { size_t gdaColumn; const GFF4Struct *gdaRow = getRowColumn(row, columnHash, gdaColumn); if (!gdaRow) return def; return gdaRow->getDouble(gdaColumn, def); } float GDAFile::getFloat(size_t row, const Common::UString &columnName, float def) const { size_t gdaColumn; const GFF4Struct *gdaRow = getRowColumn(row, columnName, gdaColumn); if (!gdaRow) return def; return gdaRow->getDouble(gdaColumn, def); } GDAFile::Type GDAFile::identifyType(const Columns &columns, const Row &rows, size_t column) const { if (!columns || (column >= columns->size()) || !(*columns)[column]) return kTypeEmpty; if ((*columns)[column]->hasField(kGFF4G2DAColumnType)) { const Type type = (Type) (*columns)[column]->getUint(kGFF4G2DAColumnType, -1); switch (type) { case kTypeEmpty: case kTypeString: case kTypeInt: case kTypeFloat: case kTypeBool: case kTypeResource: break; default: throw Common::Exception("Invalid GDA column type %d", (int) type); } return type; } if (!rows || rows->empty() || !(*rows)[0]) return kTypeEmpty; GFF4Struct::FieldType fieldType = (*rows)[0]->getFieldType(kGFF4G2DAColumn1 + column); switch (fieldType) { case GFF4Struct::kFieldTypeString: case GFF4Struct::kFieldTypeASCIIString: return kTypeString; case GFF4Struct::kFieldTypeUint8: case GFF4Struct::kFieldTypeUint16: case GFF4Struct::kFieldTypeUint32: case GFF4Struct::kFieldTypeUint64: case GFF4Struct::kFieldTypeSint8: case GFF4Struct::kFieldTypeSint16: case GFF4Struct::kFieldTypeSint32: case GFF4Struct::kFieldTypeSint64: return kTypeInt; case GFF4Struct::kFieldTypeFloat32: case GFF4Struct::kFieldTypeFloat64: return kTypeFloat; default: break; } return kTypeEmpty; } void GDAFile::load(Common::SeekableReadStream *gda) { try { _gff4s.push_back(new GFF4File(gda, kG2DAID)); const uint32 version = _gff4s.back()->getTypeVersion(); if ((version != kVersion01) && (version != kVersion02)) throw Common::Exception("Unsupported GDA file version %s", Common::debugTag(version).c_str()); const GFF4Struct &top = _gff4s.back()->getTopLevel(); _columns = &top.getList(kGFF4G2DAColumnList); _rows.push_back(&top.getList(kGFF4G2DARowList)); _rowStarts.push_back(_rowCount); _rowCount += _rows.back()->size(); _headers.resize(_columns->size()); for (size_t i = 0; i < _columns->size(); i++) { if (!(*_columns)[i]) continue; _headers[i].hash = (uint32) (*_columns)[i]->getUint(kGFF4G2DAColumnHash); _headers[i].type = identifyType(_columns, _rows.back(), i); _headers[i].field = (uint32) kGFF4G2DAColumn1 + i; } } catch (Common::Exception &e) { e.add("Failed reading GDA file"); throw; } } void GDAFile::add(Common::SeekableReadStream *gda) { try { _gff4s.push_back(new GFF4File(gda, kG2DAID)); const uint32 version = _gff4s.back()->getTypeVersion(); if ((version != kVersion01) && (version != kVersion02)) throw Common::Exception("Unsupported GDA file version %s", Common::debugTag(version).c_str()); const GFF4Struct &top = _gff4s.back()->getTopLevel(); _rows.push_back(&top.getList(kGFF4G2DARowList)); _rowStarts.push_back(_rowCount); _rowCount += _rows.back()->size(); Columns columns = &top.getList(kGFF4G2DAColumnList); if (columns->size() != _columns->size()) throw Common::Exception("Column counts don't match (%u vs. %u)", (uint)columns->size(), (uint)_columns->size()); for (size_t i = 0; i < columns->size(); i++) { const uint32 hash1 = (uint32) (* columns)[i]->getUint(kGFF4G2DAColumnHash); const uint32 hash2 = (uint32) (*_columns)[i]->getUint(kGFF4G2DAColumnHash); const Type type1 = identifyType( columns, _rows.back(), i); const Type type2 = identifyType(_columns, _rows[0] , i); if ((hash1 != hash2) || (type1 != type2)) throw Common::Exception("Columns don't match (%u: %u+%d vs. %u+%d)", (uint) i, hash1, (int)type1, hash2, (int)type2); } } catch (Common::Exception &e) { e.add("Failed adding GDA file"); throw; } } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/gdafile.h000066400000000000000000000121351331663051500200220ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's GDAs (2DAs, two-dimensional array, within V4.0 GFFs). */ #ifndef AURORA_GDAFILE_H #define AURORA_GDAFILE_H #include #include #include #include "src/common/ustring.h" #include "src/common/ptrvector.h" #include "src/aurora/types.h" namespace Common { class UString; class SeekableReadStream; } namespace Aurora { /** Class to hold the GFF'd two-dimensional array of a GDA file. * * GDAs works very similar to 2DA files (see TwoDAFile in 2dafile.h). * But instead of keeping the data inside a simple ASCII or binary * format, GDAs store their table data inside a V4.0 GFF. * * Moreover, GDAs do not contain column headers as strings. Instead, * they only store the CRC32 hash of the lower-case string encoded * in UTF-16LE. As such, it is not possible to directly list the * column names of a GDA without prior knowledge. * * Several GDAs with the same column layout can also be combined into * an MGDA, creating a merged, combined table. This is commonly used * by the Dragon Age games. Within these MGDAs, rows are not anymore * identified by raw row index (since this index is now meaningless), * but by an "ID" column. */ class GDAFile : boost::noncopyable { public: static const size_t kInvalidColumn = SIZE_MAX; static const size_t kInvalidRow = SIZE_MAX; enum Type { kTypeEmpty = -1, kTypeString = 0, kTypeInt = 1, kTypeFloat = 2, kTypeBool = 3, kTypeResource = 4 }; struct Header { uint32 hash; Type type; uint32 field; Header() : hash(0), type(kTypeEmpty), field(0xFFFFFFFF) { } }; typedef std::vector
Headers; /** Take over this stream and read a GDA file out of it. */ GDAFile(Common::SeekableReadStream *gda); ~GDAFile(); /** Add another GDA with the same column structure to the bottom of this GDA. * * This effectively pastes the GDAs together, creating one combined table. * Note that the row numbers will be continuous and therefore will be * different depending on the order of the pasting, making them useless * for row identification. An ID column should be used for this case. * * The ownership stream will be transferred to this GDAFile object. */ void add(Common::SeekableReadStream *gda); /** Return the number of columns in the array. */ size_t getColumnCount() const; /** Return the number of rows in the array. */ size_t getRowCount() const; /** Does this row exist in the GDA? */ bool hasRow(size_t row) const; /** Get the column headers. */ const Headers &getHeaders() const; /** Get a row as a GFF4 struct. */ const GFF4Struct *getRow(size_t row) const; /** Find a row by its ID value. */ size_t findRow(uint32 id) const; /** Find a column by its name. */ size_t findColumn(const Common::UString &name) const; /** Find a column by its hash. */ size_t findColumn(uint32 hash) const; Common::UString getString(size_t row, uint32 columnHash, const Common::UString &def = "") const; Common::UString getString(size_t row, const Common::UString &columnName, const Common::UString &def = "") const; int32 getInt(size_t row, uint32 columnHash, int32 def = 0) const; int32 getInt(size_t row, const Common::UString &columnName, int32 def = 0) const; float getFloat(size_t row, uint32 columnHash, float def = 0.0f) const; float getFloat(size_t row, const Common::UString &columnName, float def = 0.0f) const; private: typedef Common::PtrVector GFF4s; typedef const GFF4List * Columns; typedef const GFF4List * Row; typedef std::vector Rows; typedef std::vector RowStarts; typedef std::map ColumnHashMap; typedef std::map ColumnNameMap; GFF4s _gff4s; Headers _headers; Columns _columns; Rows _rows; size_t _rowCount; RowStarts _rowStarts; mutable ColumnHashMap _columnHashMap; mutable ColumnNameMap _columnNameMap; void load(Common::SeekableReadStream *gda); Type identifyType(const Columns &columns, const Row &rows, size_t column) const; const GFF4Struct *getRowColumn(size_t row, uint32 hash, size_t &column) const; const GFF4Struct *getRowColumn(size_t row, const Common::UString &name, size_t &column) const; }; } // End of namespace Aurora #endif // AURORA_GDAFILE_H xoreos-tools-0.0.5/src/aurora/gdaheaders.cpp000066400000000000000000003216411331663051500210560ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Resolve a GDA column header hash back to its string. */ #include "src/common/util.h" #include "src/common/binsearch.h" #include "src/aurora/gdaheaders.h" namespace Aurora { typedef Common::BinSearchValue GDAHeaderHash; /** All currently known GDA column header strings, together with their CRC32 hashes. * * Note: For the binary search to work, this list needs to stay sorted by hash value! */ static const GDAHeaderHash kGDAHeaderHashes[] = { { 1421660U, "AttackScatter" }, { 3607720U, "DIScanCode" }, { 4376397U, "FPS" }, { 6714328U, "SpecialCase" }, { 7038726U, "Bank3" }, { 8828510U, "Sylvan" }, { 8937265U, "Draw_Weapon" }, { 9293919U, "Closed_Unlocked" }, { 12124062U, "Test2" }, { 14904291U, "Top0" }, { 15699404U, "A5" }, { 17060417U, "TargetFade" }, { 21861984U, "Used" }, { 22033083U, "Projectile" }, { 23668384U, "Button3" }, { 24195820U, "RuneCount" }, { 25383073U, "Orz200ar_Commons" }, { 26291545U, "ChaseTable" }, { 28006648U, "Extreme_Effect" }, { 28895966U, "CanRotateIcon" }, { 36343957U, "WidgetType" }, { 38134867U, "Facing" }, { 42582947U, "NumberRings" }, { 44583290U, "Prop1Value" }, { 48449665U, "Queue" }, { 49643810U, "Inescapable" }, { 51797261U, "WaspSwarm" }, { 51929172U, "Game_CbtStrFSpeed" }, { 55381987U, "DRMod" }, { 55683016U, "LookDownAnimation" }, { 59147525U, "Loops9" }, { 60769971U, "FGlowIntensity" }, { 61447571U, "Opening" }, { 61946878U, "Open_2" }, { 62325948U, "AbilityScoreModifier" }, { 62550588U, "Animation1" }, { 63435298U, "Condition" }, { 63456459U, "SliderMin" }, { 65813985U, "NrrgalWorker" }, { 69936867U, "CharGenLabel" }, { 70083147U, "Weapon13" }, { 73189044U, "Apr" }, { 73889260U, "Idle2" }, { 74508159U, "Effect1_Resource" }, { 75921650U, "Mage1" }, { 78333924U, "PC" }, { 79362247U, "DefaultNameFemale" }, { 81184778U, "PrereqAbility" }, { 81635738U, "RewardStrRef" }, { 82090968U, "Action6" }, { 86764033U, "Appearance" }, { 92240245U, "DamageStrRef1" }, { 93174895U, "Extra1" }, { 93648475U, "Warrior8" }, { 95998482U, "Disabled_Weapon_Sounds" }, { 97523184U, "BackgroundTable" }, { 97640263U, "CranePuzzle" }, { 98250892U, "DisplayStr3" }, { 100880733U, "MasterTemplate" }, { 103378247U, "SpellScript" }, { 104956291U, "Auto_Remove" }, { 105401216U, "HideLaunch" }, { 105467695U, "AnimSpeed" }, { 106843480U, "Maximum_Range" }, { 109660124U, "Duration" }, { 112392041U, "Bhn100cr_Rat" }, { 112745350U, "Type_Use" }, { 113233188U, "ConditionLabel" }, { 113271235U, "AttackFlWidth" }, { 116043176U, "ArmorPerLevel" }, { 116982239U, "ShakeType" }, { 120860322U, "Condition_Mode" }, { 121391276U, "ArmyBufferMax" }, { 121969149U, "StrAdjust" }, { 121999331U, "WeaponScale" }, { 122537988U, "ModalabilityBlendTree" }, { 123905048U, "FResistanceMaximum" }, { 124259164U, "LowerStrRef" }, { 126523709U, "NocturnScout" }, { 127328571U, "ImpactTimeout" }, { 132538785U, "Switch2_Class" }, { 133119168U, "DisableLookAt" }, { 133492742U, "Speed" }, { 137764198U, "String_Description_Technical"}, { 137912134U, "ShowRegardless" }, { 141090729U, "Position" }, { 142817396U, "ArmyTotalMax" }, { 144909505U, "Eyes_Worksheet" }, { 148813584U, "AttributePoints" }, { 151762438U, "PowerPod" }, { 152745570U, "OpposingAI" }, { 158145021U, "EventName" }, { 158150364U, "Icon4" }, { 158468564U, "Cir340ar_Fade_Templar_Night" }, { 159676877U, "Human" }, { 163068403U, "DiceTest" }, { 165682124U, "MediumBoots" }, { 166026344U, "Den211ar_Arl_Eamon_Estate_1" }, { 166594787U, "Rogue8" }, { 168961103U, "TS_HighTable" }, { 170570597U, "UseCommonGestures" }, { 172161555U, "Scale" }, { 172521407U, "MaxAnimationYaw" }, { 175395745U, "ShowOnSelf" }, { 177236338U, "Win32LocaleID" }, { 178686292U, "Omega" }, { 181568409U, "Rumble_Type" }, { 188312821U, "Movement_BlendTree" }, { 190481838U, "MaxSpeed" }, { 194200504U, "FlagSold" }, { 201332038U, "Frequency" }, { 202000020U, "ModelPath" }, { 206109278U, "FFogColor0" }, { 207936954U, "PrecacheWaveData" }, { 212353258U, "RandChance" }, { 214037785U, "SpecPoints" }, { 214256908U, "CrustID" }, { 217159566U, "Major" }, { 218438067U, "IdleLeft" }, { 219074858U, "Medium" }, { 221805479U, "FilterEquipment" }, { 230943666U, "Game_CbtSpeed" }, { 231543438U, "Shield" }, { 231863489U, "Height" }, { 234285194U, "Command" }, { 234932771U, "100061" }, { 235767865U, "APBase" }, { 235772159U, "BasePriority" }, { 239140105U, "Icon16" }, { 239588056U, "WeightWarrior" }, { 240147400U, "AOE_Index" }, { 240253765U, "Weight8" }, { 243621393U, "Hostility" }, { 255100003U, "AttackLeech" }, { 258221097U, "TargetType" }, { 268811058U, "Bullet" }, { 269175082U, "Type_Category" }, { 271665430U, "Damage1" }, { 273492170U, "Effect4_Float2" }, { 275566037U, "EngineLink" }, { 275937400U, "Anim_CbtSpeed" }, { 276050140U, "Orz100ar_Mountain_Pass" }, { 276176797U, "Icon5" }, { 278409112U, "StartingCharges" }, { 282710090U, "DateFormat" }, { 283459715U, "MaxBlur" }, { 284038808U, "ExploreScale" }, { 285860889U, "BlendTreeName" }, { 296588017U, "AttackBRRing" }, { 299361257U, "FCloudRangeMultiplier2" }, { 299891537U, "Den974ar_Rogue_K" }, { 300173649U, "FDeathBlow" }, { 301153996U, "NameStrRef1" }, { 305348204U, "Show_Progress" }, { 305735670U, "AttackArmorPiercing" }, { 307130823U, "Neutral" }, { 309174154U, "MeleeRingDisabledEnd" }, { 309693073U, "AttackFR_Reach" }, { 311884604U, "StrIDDesc" }, { 312484724U, "Type" }, { 312895368U, "InjuryMax" }, { 313239950U, "AttackFRRing" }, { 313340222U, "DonationScript" }, { 316961852U, "IsTutorial" }, { 317131746U, "Mask" }, { 320748900U, "FBloomVBlurWidth" }, { 327831836U, "TintColor" }, { 335144827U, "FCloudDepth" }, { 337025345U, "SoundImpact" }, { 338373011U, "BaseAttack" }, { 345355522U, "Major_Effect" }, { 351631277U, "Cli400ar_City_Gates" }, { 353347367U, "Rank" }, { 353593310U, "RumblePattern" }, { 355201928U, "StaminaUpkeep" }, { 356206790U, "AttackFL_Angle" }, { 356254124U, "AttributeValue" }, { 357813023U, "FFogColor1" }, { 358332623U, "Respawn" }, { 362825144U, "WeaponOffset" }, { 365187742U, "AttackBack" }, { 365472634U, "AcceptStrRef" }, { 370351214U, "Luck" }, { 374225939U, "HelmModelVariation" }, { 376642509U, "ArmourPenetration" }, { 378792221U, "KronWarrior" }, { 379833238U, "ActionSet" }, { 381681950U, "Helmet" }, { 384414793U, "Set2" }, { 386629853U, "BaseArmorPenetration" }, { 387808467U, "Template" }, { 388364897U, "Exit" }, { 388489002U, "Resist1" }, { 389180699U, "DestroyVFX" }, { 389910404U, "CharybEmerald" }, { 390777821U, "AllowInstant" }, { 391845401U, "OrientationZ" }, { 393084110U, "ShakeDuration" }, { 393353036U, "StrengthModifier" }, { 393916426U, "MaxCount" }, { 395537274U, "E1011" }, { 399523528U, "Background" }, { 401839034U, "Cooldown" }, { 402355206U, "SoundDuration" }, { 409681986U, "AverageGiftValue" }, { 410130401U, "Button2" }, { 410244073U, "LastName" }, { 417591947U, "GlovesModelVariation" }, { 418010895U, "MeleeRingsData" }, { 422542238U, "SetTotal" }, { 424251708U, "HasIcon" }, { 426792519U, "Bank2" }, { 427966477U, "RestartCooldown" }, { 430165727U, "Test3" }, { 434820324U, "Precision" }, { 435469453U, "A4" }, { 435706530U, "Top1" }, { 435939347U, "RulesRace" }, { 436197576U, "AreaSound" }, { 436356403U, "AreaTag" }, { 441910439U, "PlayerChoice" }, { 442252728U, "Cir200ar_Tower_Level_1" }, { 446301406U, "AirSkiffBoarders" }, { 446301495U, "EffectResisted" }, { 446542916U, "Loops8" }, { 448620133U, "String_ToolTip" }, { 450830773U, "ToolTipOrder" }, { 454939259U, "LargeShieldLevel" }, { 455333445U, "Height_F" }, { 457565276U, "FastBodyDecay" }, { 458561398U, "Xbox360" }, { 459129800U, "ArmorGloves" }, { 465087263U, "Crust_Effect" }, { 466929058U, "Count" }, { 467566277U, "Power" }, { 467896477U, "TotalEntries" }, { 469220555U, "ShakeYFreq" }, { 469627836U, "EquipEvent" }, { 469879395U, "StartState" }, { 471570315U, "Cover" }, { 471793379U, "DamageBase" }, { 471864314U, "GestureProbability" }, { 473822677U, "E1020" }, { 474069449U, "PortraitPalette" }, { 475070168U, "Encounters1" }, { 475640144U, "Playable" }, { 476496821U, "Effect3_Int1" }, { 477931057U, "AutoTarget" }, { 480685819U, "StartingClass" }, { 480819987U, "SoundID" }, { 480850684U, "NrrgalWarrior" }, { 482345421U, "DisplayStr2" }, { 482801730U, "ModelVariation" }, { 483423542U, "Walkmesh" }, { 485030011U, "SoundDurationVolume" }, { 485993930U, "FailureVFX" }, { 490099466U, "Weapon12" }, { 501497862U, "WeaponWield" }, { 501916138U, "RemoveWhenDead" }, { 502085276U, "ArmorBonus" }, { 503294617U, "Action7" }, { 505940847U, "LightYAdjust" }, { 507292028U, "AttachScale" }, { 508717349U, "IdleRight" }, { 510075347U, "Achievement" }, { 516713787U, "Rumble_BaseIntensity" }, { 519759590U, "AppearVFX" }, { 523692622U, "GeneratePerFollower" }, { 524419732U, "BConsiderHostile" }, { 524451592U, "Action12" }, { 527143153U, "Default_Sound_Set" }, { 527232728U, "AttackBLWidth" }, { 528951897U, "Stat" }, { 532773143U, "HSVContrast" }, { 534088598U, "InventorySmallIcon" }, { 537308113U, "FocusDistance" }, { 538851679U, "CanFlee" }, { 542698763U, "Type_Cost" }, { 545276281U, "SubCommand" }, { 547060113U, "IsPlotShape" }, { 551989405U, "LaserSentinel" }, { 552037852U, "MapTitle" }, { 553309852U, "MiniMapPin" }, { 556327241U, "WeaponTable" }, { 556880460U, "Ntb210ar_Brecilian_Forestne" }, { 557052645U, "FResistanceModifier" }, { 558482149U, "AttackBR" }, { 561196209U, "Offset" }, { 562937546U, "Table5" }, { 567233250U, "WieldType" }, { 568406850U, "ArmourValue" }, { 569414898U, "Reward" }, { 569761468U, "ShowDonationButton" }, { 570895252U, "Damage3" }, { 571803576U, "WeaponBowStrRef" }, { 572733205U, "FocalRadius" }, { 573963242U, "UVAnimSpeed" }, { 574651679U, "Icon7" }, { 578153022U, "WeaponBowLevel" }, { 584200531U, "MovementTable" }, { 591372477U, "RaceAbility" }, { 592308015U, "AttackBlast" }, { 600136782U, "NameStrRef3" }, { 613447705U, "SynchAnim" }, { 613840734U, "LocalizationTag" }, { 616634588U, "AvoidMeleeenEmies" }, { 619652321U, "Resist29" }, { 619856184U, "ScrollSpeedY" }, { 621919656U, "Resist3" }, { 627930267U, "OrientationX" }, { 627945162U, "Icon15" }, { 629825572U, "ArmorProps" }, { 633431445U, "NextID" }, { 638368012U, "Ntb200ar_Brecilian_Forestnw" }, { 641893199U, "DmgScalingThresh" }, { 642686768U, "Den500ar_Arl_Exterior" }, { 643117804U, "ReqProp2Mod" }, { 645531618U, "Dmg_Flags" }, { 648283245U, "Material9" }, { 649384513U, "ToolTip" }, { 649989203U, "GoReLevel" }, { 650030685U, "Boots" }, { 659615381U, "BaseManaStamina" }, { 660264680U, "ImpactVFX" }, { 662478783U, "To" }, { 662593128U, "CostUpkeep" }, { 664900028U, "PrecollisionUVAnimName" }, { 669506298U, "AttributeID" }, { 669915811U, "Animation_Override" }, { 672560738U, "BootsModelTint" }, { 673229691U, "IsPlot" }, { 673256352U, "Georg_Test" }, { 673436973U, "Variation" }, { 676703212U, "React" }, { 678408551U, "PrecollisionTextureAnimName" }, { 678931606U, "EffectResistance" }, { 680993279U, "Animation2" }, { 681261933U, "Left5" }, { 683738427U, "Closed_Locked" }, { 684336042U, "AttackBLRing" }, { 684797042U, "Modifier" }, { 685785939U, "Positional_Type" }, { 688000362U, "GunPawn" }, { 689116208U, "BottomScreenType" }, { 698258082U, "SuperSonicBase" }, { 698879837U, "TreeID" }, { 699195393U, "EnemyFlankBonus" }, { 702494183U, "ChanceToFail" }, { 703914747U, "ProbabilityModifier" }, { 706409779U, "FollowerAI" }, { 709193354U, "Title" }, { 713808508U, "PressurePlate" }, { 714224051U, "Cli700ar_Markets" }, { 728489119U, "ConjureVFX" }, { 734191119U, "A6" }, { 734795989U, "AttackFLRing" }, { 734935072U, "Top3" }, { 735260114U, "Prio" }, { 739006026U, "TS_ItemNum" }, { 740392269U, "CancelOnPlotEvent" }, { 740609531U, "FMoonAlpha" }, { 741315769U, "Table" }, { 742774051U, "Simple" }, { 743366305U, "Multiplier" }, { 745217151U, "DefaultWeapon" }, { 748508185U, "LightGloves" }, { 748562610U, "TravelWaterSlide" }, { 752030797U, "Stone_Golem" }, { 755638087U, "DamageInfo" }, { 757587883U, "SoundSet" }, { 758267220U, "WeaponSet2LeftStack" }, { 760745214U, "Orz530ar_Ortan_Thaig" }, { 761761592U, "StrID_Effect" }, { 762325979U, "Major_Facing" }, { 762584458U, "Action10" }, { 777136822U, "DamageStrRef2" }, { 780131386U, "CombatVFXTester" }, { 780600894U, "Fur" }, { 781319190U, "ParameterWorksheet" }, { 783767132U, "AOE_Type" }, { 784959010U, "FDistanceMultiplier" }, { 788541832U, "Weapon10" }, { 789102311U, "FastAngle" }, { 792836686U, "Resist18" }, { 793388591U, "Idle1" }, { 794244628U, "FStealingModifier" }, { 796695736U, "ArmySpawnWP" }, { 797070517U, "FSunIntensity" }, { 798515487U, "MissileDeflection" }, { 798966067U, "Sound_X" }, { 799357003U, "Ability9" }, { 799746865U, "Mage2" }, { 800606204U, "FrayleighMultiplier" }, { 801696160U, "BaseHealth" }, { 801753115U, "Action5" }, { 801777985U, "ThousandSeparator" }, { 804927328U, "Effect4_Resource" }, { 805082355U, "ExploreMicroPortrait" }, { 806781662U, "Amulet" }, { 809634884U, "AllowedList" }, { 815716057U, "Gloves" }, { 817532226U, "IsSpecial" }, { 818480006U, "VaultID" }, { 819084727U, "2da" }, { 823930364U, "BlendOut" }, { 829691757U, "AddInUID" }, { 830474796U, "Left4" }, { 831262910U, "Animation3" }, { 839215464U, "HeavyArmorStrRef" }, { 842287077U, "FadeoutTime" }, { 843608276U, "Unlocked" }, { 844711912U, "Skeleton" }, { 844876799U, "Captain" }, { 844957060U, "Bank1" }, { 846426395U, "Editor" }, { 846460685U, "NameStrRef" }, { 852822369U, "Top2" }, { 853143374U, "A7" }, { 857689869U, "FireWait" }, { 859215507U, "MarkupTag" }, { 859320354U, "Switch1_Level" }, { 861881378U, "Button1" }, { 864926133U, "Blend" }, { 875636771U, "HeraldryFile" }, { 879701195U, "Action11" }, { 882956673U, "Flesh" }, { 885148109U, "BottomScreenID" }, { 886840987U, "Melee" }, { 887292623U, "BUsesMana" }, { 887465112U, "X4" }, { 887959913U, "Bolt" }, { 888131383U, "TalentPoints" }, { 889059708U, "Use_Condition_Mode" }, { 889372311U, "SentryDrone" }, { 890123734U, "ArmyDeathCountVar" }, { 894889380U, "JournalSort" }, { 897077506U, "CombatEffect_Precisions" }, { 897986624U, "Pil" }, { 898872317U, "DescStrID" }, { 900158400U, "Layout" }, { 901443381U, "WeaponSet2Right" }, { 902126647U, "Scaled_Field" }, { 903554986U, "SoundMatType" }, { 904673712U, "MaxWeight" }, { 904782749U, "Team4" }, { 904873550U, "Rumble_Iterations" }, { 905976579U, "ScalingVector" }, { 906178353U, "UseChance" }, { 907739337U, "Weapon11" }, { 908238860U, "SlotsLocked" }, { 911077012U, "RequiresStrRef" }, { 911167618U, "ModelRace" }, { 911313448U, "SimpleEffect" }, { 911903503U, "Resist19" }, { 913113991U, "Misc" }, { 913851120U, "AmbientOverride" }, { 914179406U, "ClosedToOpened" }, { 914576581U, "PinType" }, { 917510768U, "Mage3" }, { 918423818U, "Ability8" }, { 918461186U, "AttackBonus" }, { 919547228U, "Gold" }, { 919796058U, "Action4" }, { 920169643U, "RaptorHawk" }, { 922863136U, "Ps3" }, { 923900119U, "EventID" }, { 927029009U, "TargetResult" }, { 927538167U, "DamageStrRef3" }, { 927699062U, "Effect3_Int2" }, { 928266959U, "StepUp" }, { 930095302U, "Den964ar_End_Assassin" }, { 930483761U, "BaseClass" }, { 934087747U, "Strategy" }, { 938299918U, "DisplayStr1" }, { 942104125U, "Effect_Object0" }, { 942568561U, "MediumHelm" }, { 944686625U, "Extreme_Facing" }, { 949391243U, "Table4" }, { 950825350U, "Staff" }, { 951820807U, "PreferMelee" }, { 958419230U, "AllowPermanent" }, { 959218980U, "WeaponMeleeLevel" }, { 961531844U, "ShakeDelay" }, { 966068516U, "Expression" }, { 966213922U, "StackSize" }, { 970998895U, "TargetLevel" }, { 978058292U, "CameraXAdjust" }, { 979339582U, "PassiveTalent2" }, { 980112970U, "DefenseBonus" }, { 987655439U, "NameStrRef2" }, { 989507626U, "FCloudRangeMultiplier1" }, { 991534468U, "CombatOnly" }, { 991697621U, "Damage2" }, { 995839070U, "Icon6" }, { 995946045U, "Lot105ar_Lothering_Lc" }, { 996178697U, "Effect4_Float1" }, { 998350641U, "Humanoid" }, {1000372874U, "Effect" }, {1007324393U, "Resist2" }, {1014384090U, "OrientationY" }, {1014407051U, "Icon14" }, {1021270669U, "Cream" }, {1029174277U, "WalkWaterSlide" }, {1030739818U, "ConvNamePlural" }, {1033821394U, "PointsPer" }, {1034033145U, "ShakeYawFreq" }, {1034153634U, "Impact_Table" }, {1035312742U, "Weapon20" }, {1036314506U, "Set1" }, {1037872334U, "CastAnim_VFX" }, {1038708857U, "ScrollSpeedX" }, {1039015064U, "Urn200ar_Ruined_Temple" }, {1039406496U, "Resist28" }, {1048226227U, "VoxaiElite" }, {1048484060U, "FFogColor2" }, {1049388871U, "Arl100ar_Redcliffe_Village" }, {1055179836U, "CameraZoom" }, {1055755202U, "VFX_Deselected" }, {1055959567U, "AttackFR_Width" }, {1058702582U, "BaseDamage" }, {1069495596U, "Material8" }, {1069628897U, "Value" }, {1072399968U, "ModelSizes" }, {1075288592U, "FCloudColor2" }, {1075377373U, "PickLockFailure" }, {1077191953U, "SoundActivate1" }, {1077647898U, "DefaultValue" }, {1080246718U, "StrRef" }, {1080915046U, "FTurbidity" }, {1081407707U, "Attribute0" }, {1085105840U, "Blast" }, {1089137166U, "Secret" }, {1090612174U, "Icon11" }, {1094297119U, "Effect1_Float1" }, {1094503249U, "FCloudSharpness" }, {1095395740U, "Percentage" }, {1095827677U, "Threat_Impact" }, {1096953813U, "Misc2" }, {1098741932U, "Resist7" }, {1098911410U, "LocationVFX" }, {1109671365U, "WeaponSet1Right" }, {1110086366U, "Leucosia" }, {1110144829U, "FollowerTacticsTable" }, {1111151200U, "BCanBleed" }, {1112043480U, "TalentTable" }, {1117561743U, "Disabled_Armor_Sounds" }, {1117873628U, "Package" }, {1123158435U, "ReqPowerScale" }, {1124196876U, "ShieldStrRef" }, {1125401843U, "ValidForClass2" }, {1125547031U, "StartArea" }, {1126193056U, "Reset" }, {1131797190U, "OverlayTree" }, {1135953671U, "Variation_Worksheet" }, {1137236117U, "Animation" }, {1137932793U, "Effect4_Int2" }, {1138508078U, "Effect2_Float2" }, {1146023318U, "NumDice" }, {1151277051U, "Armadillo" }, {1155368596U, "RadialGroup" }, {1156232721U, "DamageRange" }, {1158546615U, "AttackMod" }, {1159430972U, "SuccessGrade" }, {1161224508U, "WillAdjust" }, {1162021597U, "es-es" }, {1164443854U, "Interrupt" }, {1167731541U, "SpecRoot" }, {1170047532U, "PrimaryRange" }, {1171118642U, "CollisionSound" }, {1172405198U, "Table1" }, {1175767833U, "Template3" }, {1177335835U, "Icon3" }, {1183662587U, "DescriptionStrRef2" }, {1184785604U, "PlayHumanoidAnimations" }, {1189239913U, "HeaderStrID" }, {1189372269U, "LargeIcon2" }, {1192897652U, "Lieutenant" }, {1193030555U, "Hostile" }, {1193423182U, "Amplitude_Y" }, {1193554600U, "SoundMapBank" }, {1197427016U, "Locked" }, {1197724016U, "Attribute" }, {1197810504U, "TyxisEmerald" }, {1198034238U, "HeavyBoots" }, {1201770834U, "NotificationFlag" }, {1201970273U, "ArenaModelName" }, {1203668663U, "AmbushValue" }, {1206423396U, "AttackBL_Width" }, {1210638799U, "MassiveArmorStrRef" }, {1212918477U, "Health" }, {1215524259U, "PowerRequired" }, {1216715632U, "WieldR" }, {1217293259U, "TrapDmgScale" }, {1217639316U, "MediumArmorStrRef" }, {1218058200U, "Team1" }, {1219675370U, "ProgFX" }, {1220338444U, "ChanceParent" }, {1222705433U, "Targetable" }, {1223024337U, "FSunColor2" }, {1224063131U, "Extreme_VFX" }, {1226759481U, "DexterityBase" }, {1230570688U, "Weapon8" }, {1231519594U, "Rogue" }, {1234325725U, "X1" }, {1236193562U, "FFogZenith" }, {1242790390U, "HealingModifier" }, {1245919004U, "PropertyFlags" }, {1246567377U, "Prefix" }, {1249159436U, "DepletableProgression" }, {1250117775U, "PlotID" }, {1259444388U, "TertiaryMoveLevel" }, {1261004623U, "AL_Attributes" }, {1265431692U, "Weapon14" }, {1269107999U, "Action1" }, {1269915261U, "VFX_Idle" }, {1271333407U, "AlignToGround" }, {1271393845U, "Mage6" }, {1273222663U, "DRModPlayer" }, {1282255802U, "String_Name_Lowercase" }, {1282637801U, "Cli600ar_Elven_Alienage" }, {1282849131U, "PoseSync1" }, {1286804638U, "Cir320ar_Fade_Darkspawn_Inv" }, {1288997802U, "TitleGUI" }, {1291320937U, "Left1" }, {1292626707U, "TrackName" }, {1294530358U, "BufferTime" }, {1296017560U, "BaseItem2" }, {1298081981U, "IsAudio" }, {1298588368U, "Target_Type" }, {1298864158U, "ShakeZ" }, {1300308152U, "DwarfMale" }, {1301029803U, "StartingAbility1" }, {1301412045U, "Resist30" }, {1302677678U, "EquipSlot" }, {1303495625U, "TargetWPTableID" }, {1305140635U, "BlendIn" }, {1306047343U, "SpeedX" }, {1306988130U, "Shape" }, {1308509061U, "SkillLabel" }, {1311289447U, "Button4" }, {1312685500U, "Silver" }, {1313184795U, "AutoID" }, {1315802531U, "BaseDamageReduction" }, {1319429861U, "MagAdjust" }, {1323668607U, "FPointVal" }, {1326512164U, "ReqProp1" }, {1327210026U, "EggBot" }, {1327755936U, "SoundImpactVolume" }, {1328214465U, "Bank4" }, {1328913139U, "WeaponMeleeStrRef" }, {1330059356U, "PortraitFrame" }, {1331238393U, "Switch2_Level" }, {1332708879U, "CursorID" }, {1334695051U, "Rumble_Duration" }, {1335332433U, "Area" }, {1335860944U, "EquipMask" }, {1336810251U, "A2" }, {1340467571U, "IPType" }, {1342797548U, "ModelTree" }, {1343286723U, "BaseType" }, {1343360548U, "Property" }, {1345178165U, "it-it" }, {1346516353U, "Weapon9" }, {1346782725U, "Cir350ar_Fade_Weisshaupt" }, {1350079155U, "Ranged" }, {1350909547U, "AddSound" }, {1352269548U, "Idle" }, {1352861765U, "ShowIntactics" }, {1353253814U, "DescStrRef" }, {1359017142U, "BasePrereqAbility" }, {1360189385U, "OrientWithObject" }, {1362523557U, "Hair_Worksheet" }, {1363985241U, "Size1" }, {1367397819U, "Suffix" }, {1368607545U, "ClassAbility" }, {1373981521U, "Gore_Max" }, {1377800050U, "ShieldLevel" }, {1378565738U, "XOffset" }, {1379018764U, "BaseDR" }, {1381873520U, "ArenaTextureName" }, {1382196325U, "ScaleModifier" }, {1383581133U, "Weapon15" }, {1384378074U, "CodexResRef" }, {1385328532U, "Ability12" }, {1386509576U, "WeightBlur" }, {1387280917U, "DexAdjust" }, {1388199006U, "Action0" }, {1390206836U, "Mage7" }, {1391079120U, "BDisableGore" }, {1391293631U, "CombatCache" }, {1391977607U, "APBonus" }, {1393811363U, "ChaseEnemy" }, {1394303748U, "Screen" }, {1394599588U, "Mage" }, {1397406625U, "ExtendedModule" }, {1400660754U, "E1027" }, {1404491153U, "ShowButton" }, {1407676272U, "EventScr" }, {1410704087U, "AOEVFX" }, {1412822900U, "Instant" }, {1413268743U, "WieldModelOverlay" }, {1413515507U, "CollisionAnimName" }, {1415095166U, "NCombatTraining" }, {1418381708U, "Resist31" }, {1422098990U, "SpeedY" }, {1423448814U, "TattooFile" }, {1424101090U, "UVFrame" }, {1430533312U, "Base" }, {1431448252U, "VarName" }, {1433574882U, "FScale" }, {1439686340U, "Default" }, {1440664305U, "Creature_Giant" }, {1441360454U, "Ring" }, {1441582888U, "Left0" }, {1446101120U, "Bank5" }, {1448130598U, "GFFStore_Invalid_List" }, {1449286761U, "AutoCancel" }, {1454713418U, "A3" }, {1455107783U, "ConditionBase" }, {1455219673U, "Material" }, {1455727433U, "Shield-Steel" }, {1457063892U, "Description" }, {1458606196U, "ShakePitch" }, {1460772297U, "ProcessWithEvent" }, {1462005596U, "Gender" }, {1462298181U, "Shale" }, {1463973815U, "String_Name" }, {1464961929U, "ConstitutionPerLevel" }, {1465694033U, "DefaultResource" }, {1471505569U, "TexAnimSpeed" }, {1471946011U, "EnterSync" }, {1477484083U, "CessationNodes" }, {1477978351U, "Hit" }, {1478122127U, "Icon10" }, {1479630702U, "Ligaia" }, {1483098605U, "Resist6" }, {1484332692U, "Misc3" }, {1486473115U, "Damage" }, {1487442009U, "Condition2" }, {1489089433U, "Wood" }, {1490148931U, "UseItem" }, {1490567978U, "Mud" }, {1496290384U, "SoundActivate0" }, {1497575150U, "Scorpion" }, {1500498330U, "Attribute1" }, {1501843707U, "UniqueID" }, {1505481080U, "Dmg_Type" }, {1505761334U, "Pre210ar_Flemeths_Hut_Ext" }, {1506554349U, "SubType" }, {1510962610U, "ValidForClass3" }, {1511494450U, "TargetWPTable" }, {1512200535U, "ClientLoad" }, {1515226505U, "SmallIcon" }, {1517217568U, "CrustVFX" }, {1517365817U, "VictoryTip" }, {1518196115U, "RumbleIntensity" }, {1520125712U, "HeaderTintIndex" }, {1521459413U, "SpawnChance" }, {1521798933U, "FireSpot" }, {1523611661U, "Success0a" }, {1524768162U, "BridgePuzzle" }, {1524871084U, "Root" }, {1527730666U, "OffsetZ" }, {1528504341U, "Pose1" }, {1535422151U, "CameraPitch" }, {1541076270U, "ToBlendTree" }, {1543170391U, "DamageType" }, {1545607643U, "LevelsPerAbility" }, {1545704015U, "MiniMapString" }, {1547028933U, "PauseAnimate" }, {1548828037U, "RngdPenalty" }, {1551418531U, "Resource" }, {1558442343U, "InitialSkillLabel" }, {1559271881U, "Weapon_Trail" }, {1560553710U, "FadeTime" }, {1560879490U, "ModelType" }, {1564346247U, "AOE_Idx" }, {1565249575U, "MemberName" }, {1567942634U, "Prerequisite" }, {1569459569U, "Above10_Secondary" }, {1570279467U, "DefaultMaterial" }, {1573905635U, "CanTriggerForPrc" }, {1577555688U, "PlaceablesTable" }, {1578724890U, "Crust" }, {1579589584U, "AOE_Param1" }, {1580793871U, "Amplitude_X" }, {1581103990U, "Sand" }, {1582035077U, "EffectStrRef1" }, {1585538048U, "Effect1_Duration" }, {1586539016U, "Hatchable" }, {1587291808U, "CreatureTag" }, {1588449107U, "PrimaryMove" }, {1591749853U, "ChanceEquipment" }, {1591793879U, "Desc" }, {1591881703U, "Limit" }, {1594882648U, "Template2" }, {1597475162U, "Icon2" }, {1601456351U, "ForcedArea" }, {1601544304U, "TurnRate" }, {1603694778U, "DescriptionStrRef3" }, {1605055965U, "DamagePerLevel" }, {1610081351U, "LoadProjectile" }, {1610567724U, "LargeIcon3" }, {1614120359U, "Follower_TrigOutComb" }, {1614673823U, "Advancement" }, {1614690773U, "WeaponProps" }, {1614915407U, "Weapon17" }, {1616724840U, "Slots" }, {1617620079U, "BehaviorType" }, {1619549916U, "Action2" }, {1619580266U, "Item8" }, {1620316196U, "PlotFile" }, {1620914698U, "AutoSelect" }, {1621363990U, "Ability10" }, {1621741312U, "CritChanceModifier" }, {1622494149U, "IdleAnimation" }, {1622802925U, "RespectHoldPosition" }, {1625996790U, "Mage5" }, {1630761480U, "EffectDuration" }, {1633989983U, "Sword" }, {1636926891U, "TrigOutComb" }, {1641340607U, "Max" }, {1647435361U, "SetLabel" }, {1648963252U, "LightZAdjust" }, {1650578647U, "HumanFemale" }, {1650905122U, "Points" }, {1655363253U, "MaxItemProps" }, {1656685342U, "X2" }, {1659741960U, "WeaponSet2Left" }, {1665166966U, "Permanent" }, {1666135536U, "RootBone" }, {1667875291U, "SquadsTable" }, {1668694829U, "TLKRef" }, {1668823674U, "AccessoryTable" }, {1668981211U, "Size3" }, {1672213075U, "Extreme" }, {1672954907U, "Team2" }, {1673258945U, "AnimationSpeeds" }, {1674087698U, "FSunColor1" }, {1676630809U, "Triggered" }, {1679887387U, "AreaList" }, {1680136510U, "DefaultPower" }, {1681763303U, "ReqProp2" }, {1683019108U, "Info" }, {1684820571U, "AttackOnCombatStart" }, {1686325448U, "A1" }, {1687138023U, "Top4" }, {1687992504U, "ArmorTable" }, {1689487304U, "ToolTipColor" }, {1693816754U, "MaxProperties" }, {1694567723U, "Immunity" }, {1695438083U, "Target_Range_Correction" }, {1700701943U, "HelmModelTint" }, {1703791551U, "DateTimeFormat" }, {1705630292U, "FContrast" }, {1712520027U, "BaseItem1" }, {1714304226U, "Shadow" }, {1715877236U, "Unknown" }, {1715882973U, "ShakeY" }, {1718880933U, "Rumble_Intensity" }, {1719161700U, "Overlay_BlendTree" }, {1721055339U, "AttackBL_Ring" }, {1721189173U, "SoundCessationPitch" }, {1721856104U, "StartingAbility2" }, {1722818671U, "Override" }, {1725364355U, "Closed" }, {1727412578U, "ShowMaterial" }, {1727777078U, "ID" }, {1732394383U, "ReqProp2Val" }, {1733181591U, "RangeType" }, {1733592563U, "Orz560ar_Shale_Taig" }, {1734077096U, "PoseSync2" }, {1734208093U, "OptimumRange" }, {1739877456U, "UVAnimation" }, {1741638726U, "PlotRef" }, {1741740640U, "Cir300ar_Fade" }, {1742384554U, "Left2" }, {1743119172U, "FleeTable" }, {1743148734U, "Combo9" }, {1745226635U, "Blood_Type" }, {1748571952U, "ValidForClass1" }, {1750350553U, "PassiveTalent" }, {1752896097U, "AudioEvent" }, {1753475552U, "StrengthModifierMultiplier" }, {1754512176U, "Random" }, {1755549632U, "ShakeYaw" }, {1756483508U, "AssaultDrone" }, {1760629485U, "Effect2_Float1" }, {1761487418U, "Effect4_Int1" }, {1764573847U, "Pose3" }, {1765074872U, "EdgePattern" }, {1765356392U, "OffsetX" }, {1768205143U, "Millipede" }, {1768959983U, "fr-fr" }, {1769598888U, "Filename" }, {1779758556U, "Effect1_Float2" }, {1780221216U, "Water" }, {1781282829U, "Icon12" }, {1783135871U, "Female" }, {1783594006U, "Misc1" }, {1783638895U, "Resist4" }, {1784149743U, "ScreenShotID" }, {1784688572U, "DeathBlow_Table" }, {1786994493U, "ShakePitchFreq" }, {1787983853U, "CombatRoundLimit" }, {1791773712U, "StartingXP" }, {1791945787U, "EffectChance" }, {1793367871U, "E1014" }, {1794107911U, "PackageType" }, {1794890228U, "Selectable" }, {1799014867U, "FCloudColor1" }, {1799866115U, "BHasDisappearAnim" }, {1801385690U, "Dog" }, {1801882422U, "MeleeRingDisabledStart" }, {1802350586U, "AttackBL_Reach" }, {1813199525U, "Den360ar_Slaver_Compound" }, {1814261165U, "AttackBR_Angle" }, {1818473527U, "DMPlayers" }, {1819443952U, "SwatBot" }, {1820168711U, "EffectStrRef3" }, {1821156423U, "FAtmAlpha" }, {1822814658U, "ActionTotal" }, {1825557980U, "Orphanage" }, {1825834492U, "Leech" }, {1839206968U, "DescriptionStrRef1" }, {1841291328U, "RightHand" }, {1841585889U, "GameString" }, {1841902254U, "LargeIcon1" }, {1843146524U, "Critter" }, {1843227531U, "BUseProbablityModifier" }, {1843556014U, "ArmorPiercing" }, {1845304238U, "OneShotKills" }, {1846379100U, "ArmorBoots" }, {1847400426U, "Resistance" }, {1850402857U, "SoundDurationPitch" }, {1850713868U, "Optimal_Distance" }, {1852794291U, "SuppressPropertyVFX" }, {1853783890U, "Den100ar_Brothel" }, {1857206080U, "Dmg_Function" }, {1858873357U, "Table2" }, {1867254814U, "Claws" }, {1870263889U, "Container" }, {1870458014U, "Special" }, {1870467844U, "Syrax" }, {1879631513U, "TS_HighChance" }, {1881276969U, "OffsetY" }, {1881638363U, "IxChair" }, {1882616790U, "Pose2" }, {1884768031U, "Cli800ar_Palace_District" }, {1885680587U, "TertiaryMove" }, {1886236156U, "ConditionParameter" }, {1887696852U, "WearR" }, {1895064570U, "BlendTree" }, {1900015509U, "LoadGlobal" }, {1900788385U, "TitleIcon" }, {1905885354U, "Combo_Table" }, {1905901863U, "AvoidNearbyEnemies" }, {1908993823U, "UnequipEvent" }, {1914151739U, "AlphaFade" }, {1914828946U, "FCloudColor0" }, {1923731204U, "Head_Worksheet" }, {1932106476U, "Heraldry" }, {1932802301U, "HasQuest" }, {1932986700U, "Icon13" }, {1934301742U, "Resist5" }, {1938146202U, "Condition1" }, {1940417278U, "Attack" }, {1943154587U, "NocturnCannon" }, {1943461991U, "Boss" }, {1944091781U, "StaticCollisions" }, {1947916953U, "Icon1" }, {1948428699U, "Template1" }, {1948872527U, "Beard_Worksheet" }, {1950600339U, "MinLevel" }, {1951267696U, "BumpLevel" }, {1951297390U, "EffectImpact" }, {1956284458U, "DisplayInGUI" }, {1961421461U, "CostMultiplier" }, {1963701279U, "Effect4_Duration" }, {1963707411U, "AOE_Param2" }, {1966513034U, "Prop2Value" }, {1966645520U, "Additive_Animation" }, {1968014238U, "LightArmorStrRef" }, {1969660742U, "EffectStrRef2" }, {1969837178U, "AddBehaviorSelf" }, {1969954443U, "LightBoots" }, {1970818270U, "ConditionScript" }, {1975797129U, "IgnoreAppMaxLevel" }, {1976707862U, "Controller" }, {1977488544U, "ArmyScript" }, {1978962668U, "CombatMoveTree" }, {1980446075U, "Arrow" }, {1980909877U, "PlayerClass" }, {1983393620U, "Snow" }, {1991792155U, "Sound" }, {1993675371U, "LifeTime" }, {1994170980U, "InventoryLargeIconPalette" }, {1994561005U, "XPos" }, {1994645110U, "SpecialGraphic" }, {1994767307U, "Priority" }, {1994956158U, "Event" }, {2001231285U, "ValidForTarget" }, {2002628611U, "Potions" }, {2005736378U, "CollisionTextureName" }, {2006584394U, "ArmorPenetration" }, {2008171580U, "Anim_Deselected" }, {2010117091U, "Fatigue" }, {2010585420U, "Table3" }, {2015074471U, "GroupID" }, {2015275233U, "ItemCreated" }, {2017962320U, "ShieldRating" }, {2020978272U, "FEffectDurNormal" }, {2021292997U, "Humanoid_Small" }, {2023673708U, "UnlockID" }, {2026787092U, "DoWaterSlide" }, {2029400109U, "Woodsman" }, {2032598522U, "ProfilePortraitPrefix" }, {2035979790U, "Weapon16" }, {2039705501U, "Action3" }, {2042575959U, "Ability11" }, {2043930033U, "Partsbased" }, {2045137524U, "Race" }, {2045873335U, "Mage4" }, {2048951419U, "TargetTypeLabel" }, {2049285982U, "ArmyTable" }, {2050591481U, "AnimName" }, {2050879840U, "NonCombatEffect" }, {2053214362U, "Size2" }, {2053794413U, "AttackFL" }, {2055637610U, "AttackerAnimation" }, {2056890751U, "Blunt" }, {2058122586U, "Team3" }, {2060260334U, "MeleeRingUpdateAlways" }, {2060696659U, "FSunColor0" }, {2061104355U, "SpawnSameWhenDead" }, {2062678162U, "Humanoid_Large" }, {2063119398U, "RuneSlots" }, {2063788826U, "ModelGenderOverride" }, {2066025186U, "Rating" }, {2069283410U, "OnTimeout" }, {2071093817U, "Target_Auto" }, {2071107585U, "FaceCamera" }, {2072462458U, "Switch1_Class" }, {2074358367U, "X3" }, {2075838542U, "EncounterChance" }, {2078237967U, "Set" }, {2080623492U, "Die" }, {2084374599U, "ClassStrRef" }, {2095137753U, "NumActions" }, {2095263023U, "TriggerFlagSet" }, {2097055185U, "PrereqAttValue" }, {2100896646U, "Stealth" }, {2102202263U, "NReactiveTier" }, {2105997658U, "Sound_Unarmed" }, {2106892198U, "Top5" }, {2113789027U, "DisabledStrRef" }, {2114258337U, "InvSoundType" }, {2114387257U, "MaxAllowedYaw" }, {2117442992U, "CanAct" }, {2118179817U, "PoseSync3" }, {2119848778U, "NocturnSoldier" }, {2120312040U, "BaseDuration" }, {2122132398U, "CessationModel" }, {2123536581U, "FFogIntensity" }, {2125466280U, "Den950ar_Alley_Justice_1" }, {2126617835U, "Left3" }, {2127271995U, "ChestModelTint" }, {2128017096U, "GlovesModelTint" }, {2130536447U, "Combo8" }, {2133029355U, "BlendTrees" }, {2134488944U, "AttackFL_Ring" }, {2135629165U, "Breakable" }, {2136439061U, "Looping" }, {2136832668U, "ShakeX" }, {2140056830U, "Show_Effects" }, {2140602746U, "IsSpeech" }, {2141690447U, "Resist32" }, {2142815465U, "Anim_CbtStrFSpeed" }, {2143385628U, "Exponent" }, {2147880983U, "SecondaryMove" }, {2153136386U, "Token" }, {2156696683U, "IX" }, {2160110268U, "DoNotDrop" }, {2161446662U, "MiniMapWidth" }, {2163480618U, "Grass" }, {2164268443U, "FatigueMax" }, {2168401164U, "AttComment" }, {2168416685U, "Tactics" }, {2169280470U, "Ingredient2" }, {2169473928U, "Maximum_Distance" }, {2171491163U, "StrRef4" }, {2171568990U, "Den975ar_Rogue_D" }, {2171645447U, "Abilityscorerequired2" }, {2172565285U, "Constant" }, {2173189519U, "FemaleNameStrRef" }, {2173998515U, "Bitmask" }, {2177534914U, "AreaHighlight1" }, {2177910009U, "PluralStrRef" }, {2178355567U, "A14" }, {2178819685U, "Member3" }, {2178938749U, "TopScreenType" }, {2180162436U, "Range" }, {2181445742U, "HSVHue" }, {2181884564U, "Warrior7" }, {2186952706U, "Rules" }, {2191224990U, "WeaponSet1LeftStack" }, {2192165329U, "GizoidA" }, {2194249535U, "GUITypeAggressive" }, {2196920784U, "MoveSpeed" }, {2197112974U, "BuseInCharGen" }, {2198466884U, "AnimationID" }, {2198894407U, "Ability5" }, {2200431129U, "LightXAdjust" }, {2200889004U, "OrientWithGround" }, {2203044030U, "NonEquipped" }, {2205686216U, "Modifier2" }, {2205944993U, "Item3" }, {2205976343U, "Action9" }, {2209917005U, "Huge" }, {2210137737U, "AttackBR_Ring" }, {2213155958U, "MagicalDebuf" }, {2213868866U, "Resist14" }, {2215808885U, "Combo2" }, {2216583589U, "Male" }, {2216597962U, "Loops6" }, {2220569185U, "Prop2" }, {2221506381U, "LocationY" }, {2223860817U, "AttributeMod" }, {2225042335U, "Feats" }, {2227427034U, "CombatEffect_Precisions_VFX" }, {2227520371U, "Cir100ar_Docks" }, {2233085904U, "TableResRef" }, {2238016334U, "ArenaTextureAnimation" }, {2246172466U, "Fire" }, {2247733875U, "Metal" }, {2248136550U, "AngleTarg" }, {2248595083U, "DefaultArmor" }, {2249693346U, "AcceptedFlag" }, {2249819305U, "Float0" }, {2254055456U, "From" }, {2256724988U, "Symbol" }, {2258792754U, "BlockVis" }, {2266578190U, "LargeShieldStrRef" }, {2269210010U, "Ntb100ar_Dalish_Camp" }, {2269678206U, "ReactiveLimit" }, {2271918650U, "StrengthPerLevel" }, {2273289380U, "LowQuality" }, {2275279269U, "TitleIconPalette" }, {2277740506U, "Effect2_Int1" }, {2278400518U, "SRModPlayer" }, {2279366397U, "AvoidAOEChance" }, {2285260970U, "InitialSpeed" }, {2287436658U, "Tag" }, {2287627245U, "Resist25" }, {2289118126U, "Visible" }, {2291060341U, "ProfilePortraitPalette" }, {2292776868U, "AbilityMode" }, {2295505895U, "DefaultEffectFlags" }, {2296059749U, "BloodColr" }, {2301771535U, "ArmyMoveToWP" }, {2302340088U, "OfferID" }, {2302623020U, "Slot2" }, {2305563983U, "SoundCessation" }, {2307023229U, "Anim_Selected" }, {2308108966U, "BombPawn" }, {2310598157U, "Loops12" }, {2311710602U, "Weight7" }, {2312772619U, "WeaponSet1Left" }, {2313048561U, "IsHeavy" }, {2314008506U, "Cessation_ProgFX" }, {2316389217U, "Material5" }, {2318174445U, "MicroPortrait" }, {2318295519U, "FilterAOE" }, {2319723262U, "ValidDeathBlows" }, {2322629297U, "AutoScale" }, {2325157920U, "Normal" }, {2329486531U, "Armed" }, {2336417210U, "HealthPerLevel" }, {2337223243U, "Effect4" }, {2344338982U, "Variance" }, {2344798917U, "pl-pl" }, {2348350584U, "WieldModel" }, {2350250932U, "Material10" }, {2352872143U, "HeavyArmorLevel" }, {2352951228U, "Bonus3" }, {2353000701U, "PackageIDForAI" }, {2353685530U, "SkillID" }, {2354693117U, "Y4" }, {2363520797U, "GeneratePathInfo" }, {2363921839U, "Den952ar_Alley_Justice_3" }, {2364686109U, "SpecPoint" }, {2370953018U, "Raxos" }, {2375360280U, "PreferRange" }, {2378961544U, "Count4" }, {2380290300U, "AreaWidth" }, {2382122039U, "Unsheath" }, {2383800609U, "AbilityCostModifier" }, {2384071844U, "Abi3" }, {2390103084U, "Rogue7" }, {2391868211U, "Orz520ar_Aeducan_Thaig" }, {2393431076U, "Sound_Default_Armor" }, {2395963812U, "AchievementFlag" }, {2396536324U, "Spell1" }, {2397161808U, "DurationVFX" }, {2398531649U, "Graphic" }, {2399466007U, "Scatter" }, {2399556628U, "RewardItem2" }, {2403565110U, "LevelsPerSkill" }, {2405094532U, "SecondaryMoveLevel" }, {2407608778U, "DefaultNameMale" }, {2410463603U, "E1033" }, {2412432260U, "AllowTemp" }, {2415796435U, "Cooldown_Group" }, {2416085141U, "AttachNode" }, {2418037460U, "QBBehaviour" }, {2418281581U, "Slot3" }, {2420510472U, "DamageBonus" }, {2420655810U, "CessationSound" }, {2420973991U, "Open" }, {2421151935U, "BulletVFX" }, {2422687321U, "Enter" }, {2424814557U, "ChestModelVariation" }, {2424862182U, "AIabilityUseMod" }, {2425390554U, "Distance" }, {2425910871U, "StaticTime" }, {2426390554U, "DialogTag" }, {2429736651U, "Weight6" }, {2430422578U, "Boar" }, {2432202502U, "NoPlayNext" }, {2432471995U, "Mass" }, {2434026493U, "StringReference" }, {2436771988U, "OcclusionFactor" }, {2436979372U, "Resist24" }, {2439770381U, "Generic" }, {2440773219U, "Green" }, {2440883898U, "FriendlyFire" }, {2442771046U, "ColorG" }, {2443253221U, "ModelScaleZ" }, {2444002695U, "Archer" }, {2444111690U, "Armor-Chain" }, {2444912200U, "TopScreenID" }, {2446625278U, "Property1" }, {2451756167U, "ResetDelay" }, {2452757268U, "AngleATK" }, {2454305565U, "FCloudDensity" }, {2456492446U, "MinAnimationYaw" }, {2456596402U, "GunCommander" }, {2457077293U, "AppearanceRestrictionGroup" }, {2458885129U, "Pre200ar_Korcari_Wilds" }, {2459750058U, "Shade" }, {2466937376U, "Material4" }, {2467120275U, "VFX_Selected" }, {2468231584U, "SortOrder" }, {2472045661U, "Variations" }, {2473722178U, "FEarthInScatterPower" }, {2474179178U, "Spider" }, {2475312025U, "String_Value" }, {2475781560U, "Weapon" }, {2477132903U, "TargetAnimation" }, {2477493223U, "Event2" }, {2478392023U, "Style" }, {2480522211U, "AttackFL_Width" }, {2480670932U, "InitialTalentLabel" }, {2484647422U, "MaxFatigue" }, {2484992863U, "Dirt" }, {2487204286U, "PrimaryTransition" }, {2488210060U, "Effect3_Duration" }, {2488680355U, "Range_Table" }, {2491191812U, "HumanMale" }, {2491389313U, "ArmorBase" }, {2494482129U, "DescriptionStrRef" }, {2495763070U, "ArmyBufferVar" }, {2498092949U, "Den200ar_Market" }, {2498605588U, "Above10_Resistance" }, {2500774645U, "Material11" }, {2500990046U, "VFX" }, {2502172413U, "Bonus2" }, {2507543055U, "Belt" }, {2509185992U, "Game_WalkSpeed" }, {2511453992U, "AffectPlot" }, {2515865791U, "MoneyMod" }, {2518508885U, "RewardItem3" }, {2518903197U, "VisibleFlag" }, {2521153418U, "FHealthScale" }, {2524156886U, "FBloomBrightness" }, {2524313792U, "Dead_2" }, {2531942552U, "SpellPower" }, {2533440997U, "Abi2" }, {2540167044U, "MuzzleFlashVFX" }, {2540512621U, "Rogue6" }, {2544446215U, "CameraRotation" }, {2546620689U, "DynamicCollisions" }, {2547985643U, "Inactive" }, {2549123265U, "PiercingType" }, {2549727752U, "BShowInUI" }, {2550745177U, "OpenContainerSound" }, {2551479869U, "CanDoDeathBlows" }, {2553772083U, "Value_Minimum" }, {2555881111U, "Ingredient3" }, {2557233691U, "Big" }, {2559392631U, "Model" }, {2560343945U, "Weapon1" }, {2562700393U, "DecayBehaviour" }, {2563013526U, "BitMaskVariable" }, {2563053348U, "Member2" }, {2563237122U, "Affect_Plot" }, {2563514414U, "A15" }, {2563881603U, "AreaHighlight0" }, {2565960534U, "ConditionalAppear" }, {2565995565U, "E1051" }, {2580217947U, "HitPoints" }, {2584263628U, "LevelUpTable" }, {2584430086U, "Ability4" }, {2584775058U, "AttackFR_Ring" }, {2585176924U, "Hollow_Wood" }, {2585691368U, "PlayerBase" }, {2586970705U, "StateController" }, {2590189705U, "Modifier3" }, {2590457312U, "Item2" }, {2590488150U, "Action8" }, {2596187889U, "ConjureAnim" }, {2599404547U, "Resist15" }, {2602032085U, "Warrior6" }, {2602624029U, "Attributes" }, {2603438074U, "BonusAbility" }, {2608520048U, "StringID" }, {2608669350U, "ArmyTotalVar" }, {2609523902U, "TerrainFollowRoll" }, {2613518738U, "SoundLooping" }, {2616054951U, "Ability" }, {2617323614U, "CombatTraining" }, {2618500507U, "ScrollingBackground" }, {2624978556U, "ElapsedTimeFormat" }, {2626053968U, "CommandLabel" }, {2630132911U, "WieldL" }, {2634393739U, "Loops7" }, {2634661428U, "Combo3" }, {2634892015U, "FarFade" }, {2635689629U, "E1003" }, {2636639984U, "DexBonus" }, {2638218016U, "Prop3" }, {2640422293U, "FleeProbability" }, {2641513996U, "LocationX" }, {2649242625U, "DerivdNameStrRef" }, {2649596467U, "StringRef" }, {2655317125U, "Shield-Wood" }, {2655362055U, "FixedOrientation" }, {2656079984U, "NLevelScale" }, {2656230015U, "Plot" }, {2656347466U, "ProjectileCount" }, {2660489180U, "S1" }, {2660798910U, "TrapPlaceable" }, {2663266087U, "WeaponStyle" }, {2663803510U, "Skill_1" }, {2664210376U, "TopConversation" }, {2664359000U, "WandStrRef" }, {2666294291U, "Z4" }, {2666467289U, "Additive_Facing" }, {2667754984U, "Float1" }, {2668097303U, "Immunity_Effect" }, {2669677149U, "AttackDamage1" }, {2671336833U, "RandTable" }, {2677944863U, "AttWeight" }, {2679300967U, "PaperDollTree" }, {2680898618U, "ElfFemale" }, {2682975475U, "MediumChest" }, {2684110634U, "BaseSR" }, {2685066021U, "OneHitKillArea" }, {2687893746U, "PlotNum" }, {2693010705U, "Appearance_Female" }, {2693800414U, "Warrior" }, {2698827660U, "Game_RunSpeed" }, {2700095129U, "XP" }, {2703648311U, "AmmoType" }, {2705070242U, "Material6" }, {2711913808U, "AddAnimation" }, {2712753833U, "Highlight5" }, {2718726636U, "IsStronghold" }, {2719117039U, "Slot1" }, {2719375735U, "Simulation" }, {2721971644U, "StartPosX" }, {2723798731U, "SpecialStaging" }, {2727722446U, "Loops11" }, {2729736236U, "Success0" }, {2730774884U, "UIMapping" }, {2731439909U, "CombatRating" }, {2732897353U, "Weight4" }, {2734689965U, "Probability" }, {2735849142U, "Destroyed" }, {2738126379U, "Swish" }, {2739719004U, "IDTag" }, {2740780179U, "GUID" }, {2741177323U, "Int0" }, {2741312754U, "Combo10" }, {2742499374U, "Resist26" }, {2744612711U, "ModelScaleX" }, {2745677577U, "NoTemplates" }, {2746626891U, "EffectDurationMod" }, {2748167132U, "Turret" }, {2748184609U, "Active" }, {2753173003U, "Variable" }, {2753723398U, "GUILabel" }, {2754283479U, "RewardItem1" }, {2755631801U, "MaxLevel" }, {2764228619U, "WearL" }, {2766547125U, "BasePrereqAbility2" }, {2774222831U, "Rogue4" }, {2780222578U, "Flag" }, {2782421456U, "Icon8" }, {2784325063U, "Spell2" }, {2787925106U, "ColorR" }, {2789204225U, "X" }, {2790341212U, "PrecollisionAnimName" }, {2792064960U, "Music" }, {2794026961U, "LightArmorLevel" }, {2797134934U, "MaulStrRef" }, {2797796569U, "DurationSound" }, {2802487552U, "Additive_Effect" }, {2803006591U, "Bonus0" }, {2803349474U, "ExitSync" }, {2805508215U, "Material13" }, {2805741549U, "Desc2StrID" }, {2806884310U, "ConditionBaseComment" }, {2807860230U, "ShakeTime" }, {2809758494U, "Drop_Stealth" }, {2810036184U, "TitleStrRef" }, {2810073181U, "PointCalc" }, {2811545671U, "Claw" }, {2818209673U, "Target_Range" }, {2820888284U, "StaticMovement" }, {2822579332U, "Ability6" }, {2823594293U, "DMEasy" }, {2824161803U, "Modifier1" }, {2828136209U, "Level" }, {2828225327U, "Leaves" }, {2828749969U, "Project" }, {2832836225U, "Resist17" }, {2832872719U, "ReqProp1Mod" }, {2833964177U, "Codex" }, {2836223159U, "Map" }, {2837559639U, "Warrior4" }, {2841929536U, "RewardItem" }, {2841940231U, "ConstitutionBase" }, {2843764094U, "DefaultIcon" }, {2844039698U, "GizoidB" }, {2854863270U, "LightArmor" }, {2855271166U, "TempXP" }, {2858533909U, "Ingredient1" }, {2863521035U, "Weapon3" }, {2863873581U, "TutorialStrRef" }, {2865602632U, "Value_Default" }, {2866025753U, "BlendTreeOverlay" }, {2867320833U, "AreaHighlight2" }, {2867793418U, "NumberChaoEggs" }, {2868604139U, "AreaSoundType" }, {2871184221U, "UpgradeApr" }, {2871358641U, "PrecollisionTextureName" }, {2875327739U, "ModelSubType" }, {2879618721U, "TintFile" }, {2880224208U, "Elf" }, {2881795191U, "InvSlotWidth" }, {2882905229U, "Worksheet" }, {2883168949U, "Effect2_Resource" }, {2888444988U, "Dwarf" }, {2890008990U, "FMieMultiplier" }, {2891629248U, "A9" }, {2893422876U, "ObjectMask" }, {2894447321U, "FDamageScale" }, {2894994821U, "AI_Armor_Type" }, {2896541022U, "S3" }, {2899914118U, "BottomScreenString" }, {2900769918U, "Usage" }, {2901335065U, "Effect2_Int2" }, {2901394626U, "UseType" }, {2901412084U, "Skill_3" }, {2902653451U, "DwarfFemale" }, {2902731002U, "RegenerationMod" }, {2902769563U, "Starfield" }, {2909901670U, "Creature_Group" }, {2912732670U, "Instances" }, {2915202862U, "AttackReach" }, {2915345277U, "AreaHeight" }, {2915456045U, "LanguageName" }, {2921872386U, "Radius" }, {2922075570U, "AttackFR" }, {2922079733U, "LowOcclusionFactor" }, {2922863168U, "FEffectDurNmare" }, {2928647253U, "DefensePerLevel" }, {2935092114U, "OpenedToClosed" }, {2938124350U, "Ice" }, {2938633471U, "Parts" }, {2939406857U, "Loops5" }, {2939636821U, "RockCrusher" }, {2939687179U, "APLevel" }, {2940198070U, "Combo1" }, {2942708804U, "Classification" }, {2943771042U, "Prop1" }, {2943990364U, "EnableWeaponSets" }, {2950969127U, "DetectLevel" }, {2951384827U, "NameLowerStrID" }, {2956625942U, "Warrior5" }, {2957882008U, "PerSpace" }, {2961863763U, "Dagger" }, {2962275647U, "StringText" }, {2964603234U, "Chest" }, {2966073867U, "AbilityID" }, {2966386585U, "LevelScale" }, {2968177003U, "HasTurnAttacks" }, {2969293677U, "Armor-Metal" }, {2972063173U, "Ability7" }, {2972972793U, "NameStrID" }, {2974445091U, "Item1" }, {2975607633U, "PrereqAttribute" }, {2981204198U, "CollisionTextureAnimName" }, {2982320064U, "Resist16" }, {2982866461U, "Conditions" }, {2989293859U, "Name" }, {2990398465U, "Brow" }, {2994120574U, "Copper" }, {2995632265U, "BaseCost" }, {2998385290U, "OvershootTime" }, {2998421616U, "IgnoreDeath" }, {3002742850U, "LargeIcon" }, {3003494061U, "Time" }, {3006738729U, "TreasureRank" }, {3007707847U, "ZOffset" }, {3007930008U, "KronEmerald" }, {3011865943U, "HSVSaturation" }, {3013619372U, "BShowInToolset" }, {3015109706U, "Weapon2" }, {3016467590U, "ColorCurves" }, {3017896941U, "A16" }, {3017997743U, "FHSVBrightness" }, {3018343655U, "Member1" }, {3019696448U, "AreaHighlight3" }, {3020773790U, "AttackDamage2" }, {3021738506U, "FactionName" }, {3022079364U, "Combat_BlendTree" }, {3022536018U, "Rate" }, {3022801928U, "Orz510ar_Caridins_Cross" }, {3023042482U, "ResourceName" }, {3023150196U, "ScaleGroup" }, {3024717125U, "ScuffingSound" }, {3027340285U, "de-de" }, {3029073762U, "Value_Maximum" }, {3029088245U, "CustomAI" }, {3030163814U, "Label" }, {3031987525U, "Group" }, {3032084612U, "Den600ar_Landsmeet_Chamber" }, {3032269493U, "Follower" }, {3036612968U, "DSpeed" }, {3036707906U, "PlayerID" }, {3040998273U, "A8" }, {3044067048U, "AppearDisappear" }, {3046568111U, "FromBlendTree" }, {3046828483U, "PrimaryAttribute" }, {3049161759U, "S2" }, {3051425172U, "MediumArmorLevel" }, {3051884630U, "Den400ar_Fort" }, {3052091829U, "Skill_2" }, {3056139080U, "Loops4" }, {3057327638U, "AreaFlags" }, {3057801397U, "RumbleTime" }, {3058191015U, "AprRulesFlags" }, {3059261637U, "JaggingLight" }, {3061859009U, "SecondaryTransition" }, {3063440168U, "MiniMapHeight" }, {3065612152U, "LongNameStrRef" }, {3065832028U, "PlayerRace" }, {3067226317U, "TerrainFollowPrecision" }, {3069363893U, "BouncePad" }, {3076896379U, "SourceLocation" }, {3080144698U, "Palette" }, {3083839057U, "ExploreCache" }, {3088195882U, "AttackFR_Angle" }, {3089574371U, "Material7" }, {3095726730U, "IsSpec" }, {3095844900U, "Event1" }, {3098175464U, "Highlight4" }, {3100259805U, "Repeat" }, {3103277959U, "Min" }, {3109894807U, "Armor-Leather" }, {3111816934U, "Additive" }, {3113677189U, "CameraFollow" }, {3119931524U, "Easy" }, {3121081316U, "IxFinal" }, {3121902361U, "Major_VFX" }, {3125319027U, "YPos" }, {3127642479U, "Resist27" }, {3128441514U, "Int1" }, {3129755174U, "ModelScaleY" }, {3130447832U, "ChanceTreasure" }, {3133937291U, "FFogCap" }, {3134880526U, "IconName" }, {3136641999U, "Type_Data" }, {3136936509U, "Property2" }, {3137953710U, "Slot0" }, {3139842965U, "AchievementID" }, {3139882237U, "StartPosY" }, {3141627752U, "FHG" }, {3146436923U, "Sound_MatType" }, {3146681487U, "Loops10" }, {3146809506U, "PurgeGroup" }, {3147552667U, "SoundCessationVolume" }, {3148826989U, "Success1" }, {3150794451U, "CountMage" }, {3154085128U, "Weight5" }, {3154183300U, "String_Description" }, {3155310338U, "VoxaiCitizen" }, {3155931548U, "BloodPool" }, {3157028390U, "Abi1" }, {3158341294U, "Rogue5" }, {3160612977U, "StorePanel" }, {3161679197U, "TerrianFollowData" }, {3166916753U, "Icon9" }, {3167176455U, "ConditionParameter2" }, {3167562026U, "AbilityScoreRequired" }, {3168647281U, "Icon" }, {3169737862U, "Spell3" }, {3170147855U, "cs-cz" }, {3170656785U, "Parameter" }, {3174468721U, "Notes" }, {3176680556U, "MaceStrRef" }, {3178054726U, "Anim_RunSpeed" }, {3184299446U, "LookupAnimation" }, {3186620195U, "GuardianPawn" }, {3188126447U, "CrustEffect" }, {3188280638U, "Bonus1" }, {3190004022U, "Material12" }, {3190443628U, "Orz550ar_Dead_Trenches" }, {3193117267U, "Arl200ar_Redcliffe_Castle" }, {3200736312U, "Product" }, {3202387690U, "Nodes" }, {3205285445U, "MinItemProps" }, {3206860864U, "Y" }, {3210535805U, "AttackFL_Reach" }, {3212090977U, "AvailableEquipmentSlots" }, {3213122795U, "StartTime" }, {3223400124U, "AllowPermDeath" }, {3223982083U, "StorePanelSort" }, {3226282117U, "MaxAnimationPitch" }, {3229176464U, "ConversationTheme" }, {3233343942U, "TutorialImage" }, {3233563736U, "OrientUniteable" }, {3235301362U, "PropColumn" }, {3236779956U, "E1034" }, {3238537073U, "Totems" }, {3238659137U, "AttackBL_Angle" }, {3238748222U, "DecimalSeparator" }, {3239242053U, "SoundDeactivate0" }, {3242529502U, "ImpactSound" }, {3249439924U, "Blood_Decal" }, {3254083515U, "Animations" }, {3254877640U, "HealthMod" }, {3254968026U, "HSVBrightness" }, {3255555192U, "PassiveAbi0" }, {3256973618U, "SmallIcon3" }, {3264054351U, "Count3" }, {3265233046U, "SwitchBroken" }, {3265813123U, "RotationRange" }, {3268311908U, "HowToStrRef" }, {3268637392U, "PartName" }, {3270381765U, "Combat" }, {3273151802U, "Y3" }, {3276895018U, "BlendCurves" }, {3278431855U, "Frame" }, {3279862139U, "Bonus4" }, {3280206525U, "ConversationPortrait" }, {3281192727U, "CancelTime" }, {3283562075U, "Inactive_Disabled" }, {3287497183U, "Alignment" }, {3289293964U, "Effect3" }, {3292878117U, "TileSizeX" }, {3295374029U, "Axe" }, {3296075233U, "FollowerTag" }, {3296099539U, "Skills" }, {3296158194U, "Replacement" }, {3296218711U, "GardenPositionX" }, {3297718715U, "HilightPrefix" }, {3302620885U, "Crust_ID" }, {3303481875U, "PickLockSuccess" }, {3303968480U, "Passive_ID" }, {3304958445U, "BHostile" }, {3306227511U, "Tag2" }, {3310411174U, "Material2" }, {3315896675U, "IsBoss" }, {3316592266U, "NearFade" }, {3319632813U, "Highlight1" }, {3321005272U, "MetropolisConveyor" }, {3326055794U, "SRMod" }, {3326395926U, "AttackBR_Reach" }, {3330190315U, "Slot5" }, {3331949436U, "Effect3_Float1" }, {3335108195U, "TS_LowTable" }, {3335535795U, "DexterityPerlevel" }, {3336922211U, "Resist8" }, {3340500266U, "Resist22" }, {3341678950U, "ModuleRef" }, {3341915582U, "CooldownMod" }, {3348125760U, "Cir330ar_Fade_Mage_Asunder" }, {3349094600U, "BDisabled" }, {3351453152U, "ColorA" }, {3351517635U, "SecondaryRange" }, {3351995745U, "Sound_Monster_Size" }, {3353721636U, "Condition_AppGroup" }, {3355043960U, "Result" }, {3357271082U, "Letter" }, {3358341153U, "NoticeDistance" }, {3360153171U, "Creature_Type" }, {3364450296U, "WeightMage" }, {3367422869U, "Z2" }, {3367757146U, "InactivePlot" }, {3368387340U, "LoadScreen" }, {3368927199U, "StrengthBase" }, {3373346266U, "ModuleName" }, {3374383112U, "PortraitTint" }, {3374499892U, "AnimationPackage" }, {3374767446U, "NocturnElite" }, {3377900553U, "VFX_Impact0" }, {3378017265U, "ElfMale" }, {3385002812U, "MultiDestination_VFX" }, {3387329613U, "ProcChance" }, {3387939818U, "ModelName2" }, {3395271657U, "Conditional" }, {3395304241U, "ToolTipStrRef" }, {3395337964U, "Movement1" }, {3396327154U, "GestureBlendTree" }, {3401985754U, "Show_Tactics" }, {3402570489U, "GameStrRef" }, {3403351359U, "Steel_Golem" }, {3406679328U, "WeightRogue" }, {3411220914U, "Combo5" }, {3411287379U, "Temporary" }, {3411955939U, "HeroBonus3" }, {3412004621U, "Loops1" }, {3412182292U, "Effect_Int2" }, {3426589286U, "Item4" }, {3427918208U, "Ability2" }, {3427932985U, "DefaultAttack" }, {3431059519U, "Large" }, {3434182850U, "Blue" }, {3434439557U, "Resist13" }, {3435783169U, "LODDistance" }, {3437351074U, "NocturnFlyer" }, {3438387072U, "ProgressBar" }, {3443383026U, "Bone" }, {3443460669U, "Sonic" }, {3448533363U, "Effect_Float2" }, {3449602883U, "Anim_WalkSpeed" }, {3450871232U, "ToolsetName" }, {3453288805U, "DIHexValue" }, {3453440946U, "SynchronizedCombat" }, {3456783208U, "Small" }, {3459237276U, "StrRef3" }, {3459891149U, "CorpseModel" }, {3465964971U, "FEarthReflectance" }, {3465971624U, "A13" }, {3466571938U, "Member4" }, {3467247366U, "AIcommand_Invalid" }, {3468595699U, "Effect3_Resource" }, {3468761103U, "Weapon7" }, {3471581252U, "DeathBlow_Type" }, {3472955154U, "MiscEquipped" }, {3473853936U, "Animation_Base" }, {3475300124U, "YOffset" }, {3479050997U, "Visualizer" }, {3481404569U, "Total" }, {3482668559U, "Thelxe" }, {3482722700U, "PositionX" }, {3484872528U, "AllowEquip" }, {3489467330U, "SoundSetProbability" }, {3490630172U, "Emotion" }, {3494514973U, "LowViolence" }, {3494747464U, "VFX_Impact1" }, {3494953481U, "Animation_VFX" }, {3497168302U, "Robodillo" }, {3500893005U, "Minor_VFX" }, {3502527829U, "MaxScaleLevel" }, {3503386768U, "TopScreen" }, {3503820429U, "String_Ref" }, {3505711787U, "ModelName3" }, {3508522517U, "TerrainFollowPitch" }, {3509156654U, "Gravel" }, {3509931886U, "IntAdjust" }, {3510726663U, "TopScreenString" }, {3512885761U, "HeavyChest" }, {3514723787U, "Broken" }, {3517840084U, "Z3" }, {3518693192U, "BackgroundImage" }, {3520124964U, "EventData" }, {3520217371U, "S6" }, {3521861138U, "Color" }, {3522156947U, "AreaSoundBank" }, {3522837001U, "AmbientRed" }, {3523078299U, "FBloomContrast" }, {3523281925U, "Riadne" }, {3525603675U, "TS_Money" }, {3527687756U, "Loops0" }, {3527762338U, "HeroBonus2" }, {3527944435U, "Combo4" }, {3531273301U, "Effect_Int3" }, {3538089905U, "hu-hu" }, {3540162403U, "FakeArea" }, {3544436510U, "AllowProjectileVFX" }, {3544764912U, "AreaWeight" }, {3546952750U, "FHue" }, {3549032900U, "FollowerPlot" }, {3550183989U, "ArmorType" }, {3555622367U, "Scylla" }, {3557088714U, "Inactive_Enabled" }, {3562425618U, "Warrior1" }, {3563377283U, "Threat_Use" }, {3574234808U, "NumMoves" }, {3576081191U, "Item5" }, {3576217033U, "DisabledLabel" }, {3577730123U, "EarlyFailure" }, {3578053563U, "Mage8" }, {3578279452U, "Creature_Large" }, {3578450113U, "Ability3" }, {3579510485U, "BaseAimDelay" }, {3579540365U, "MaterialGroup" }, {3580784137U, "OverrideTree" }, {3584306345U, "Anim_Deselected_Loop" }, {3584606049U, "Currency" }, {3584971460U, "Resist12" }, {3585125922U, "EquippableSlots" }, {3590573002U, "ArtifactBlur" }, {3591498606U, "InitialTalentID" }, {3593680700U, "Summoned_Template" }, {3594654819U, "DerivdTtipStrRef" }, {3594826938U, "InitialSkillID" }, {3595590305U, "CreatureProp" }, {3599569101U, "PositionY" }, {3608555600U, "Ingredient4" }, {3610571997U, "StrRef2" }, {3614706721U, "Quiver" }, {3616388841U, "A12" }, {3616697880U, "Orz540ar_Anvil_Of_The_Void" }, {3619386215U, "StrID" }, {3619864304U, "SlowAngle" }, {3619927371U, "Creature_Small" }, {3620801830U, "CreatureID" }, {3621398862U, "Weapon6" }, {3624523780U, "SoundDeactivate1" }, {3625297033U, "Den951ar_Alley_Justice_2" }, {3626729665U, "TriggerPlotFlag" }, {3626808234U, "Rogue1" }, {3627024582U, "AppearanceRating" }, {3633303845U, "MinWeight" }, {3633761261U, "RankRating" }, {3636133701U, "Den970ar_Franderel_Estate" }, {3640343709U, "AlwaysDraw" }, {3640740754U, "Subtitles" }, {3643543327U, "Feffectdurhard" }, {3643811693U, "Disabledcursorid" }, {3644612993U, "Hardcore" }, {3646815623U, "ConAdjust" }, {3648819397U, "Flags" }, {3653759900U, "ParameterTable" }, {3656261301U, "IsNegative" }, {3656804085U, "E1035" }, {3657655419U, "Y2" }, {3659770047U, "TacticsPreset" }, {3662209561U, "Sound_Footstep_Type" }, {3665278348U, "Wand" }, {3666259233U, "ImageRepeat" }, {3672431091U, "SliderMax" }, {3672807951U, "Tornado" }, {3673647843U, "MinAnimationPitch" }, {3673905671U, "TalentLabel" }, {3673918379U, "PowerScale" }, {3674795958U, "Xbox" }, {3675317561U, "PassiveAbi1" }, {3675711535U, "BottomScreen" }, {3676649625U, "CameraZAdjust" }, {3676754820U, "MinSpeed" }, {3678029939U, "SmallIcon2" }, {3678150485U, "FEffectDurCasual" }, {3678486078U, "Viral" }, {3679415459U, "CommandType" }, {3679752029U, "GenderName" }, {3680500760U, "CostModifier" }, {3681554153U, "Effect1_Int2" }, {3684087054U, "Count2" }, {3684241138U, "ProjectileCrust" }, {3687278596U, "Armor-Cloth" }, {3688663088U, "BDropStealth" }, {3691656822U, "Tag3" }, {3691997834U, "InvSlotHeight" }, {3693739545U, "HeavyGloves" }, {3695963367U, "Material3" }, {3696343373U, "BlendTime" }, {3701248653U, "Neck_Model" }, {3701848269U, "Comment" }, {3702596860U, "BaseDefense" }, {3704005356U, "Highlight0" }, {3704973875U, "MagicalBuff" }, {3709179341U, "Effect2" }, {3711341858U, "Anim_Selected_Loop" }, {3712760058U, "CountWarrior" }, {3712977050U, "MaxAllowedPitch" }, {3713950820U, "TileSizeY" }, {3713953536U, "Texture" }, {3714165007U, "ChanceMoney" }, {3714285334U, "GardenPositionY" }, {3715047050U, "Rock" }, {3715622303U, "CodexFlag" }, {3719478560U, "Gentleman" }, {3721023851U, "ru-ru" }, {3722492933U, "Anim" }, {3723278907U, "Layering" }, {3724594283U, "Resist23" }, {3725900464U, "ShakeRoll" }, {3727849837U, "GUIType" }, {3729993661U, "GroupType" }, {3731832628U, "RelativeValue" }, {3732920034U, "Click" }, {3732976664U, "CombatModelTree" }, {3734176102U, "Target" }, {3736328496U, "ConditionFollower" }, {3736339053U, "EliteBoss" }, {3740457577U, "RateMax" }, {3741378457U, "ResRef" }, {3747977898U, "Slot4" }, {3748127644U, "Immunity_Ability" }, {3748560500U, "PrimaryMoveLevel" }, {3748899975U, "ValidForTargetComment" }, {3750969356U, "Weight1" }, {3757987106U, "Resist9" }, {3758389027U, "ControlData" }, {3759587088U, "BHasAppearAnim" }, {3761150793U, "Class" }, {3763115735U, "Effect_Int1" }, {3765591246U, "Loops2" }, {3766372977U, "Combo6" }, {3772772313U, "Type_UI" }, {3776248710U, "AmbientGreen" }, {3777353541U, "Category" }, {3779149075U, "Puddle" }, {3779980591U, "Movement2" }, {3783193444U, "PrereqLevel" }, {3784301918U, "Auto_Apply" }, {3785332913U, "EnableCollisionEvent" }, {3785946346U, "AbilityType" }, {3787786014U, "BRestricted" }, {3788879801U, "Urn100ar_Cultists_Village" }, {3790809094U, "Frequency_Y" }, {3793223813U, "DropTable" }, {3796132863U, "BoardID" }, {3796567885U, "CombatEffect" }, {3797788353U, "ParentCategory" }, {3798736744U, "Success1a" }, {3800491056U, "PauseRate" }, {3802650159U, "Width" }, {3804206285U, "TyxisWarrior" }, {3804399657U, "ModelName1" }, {3809681793U, "DefeatTip" }, {3810745643U, "HandleFlag" }, {3810991966U, "CanRunForPrc" }, {3812050623U, "Defense" }, {3812325467U, "Minor_Effect" }, {3813617881U, "Use_Condition_Group" }, {3813741249U, "AutoDraw" }, {3813982793U, "BottomConversation" }, {3814846900U, "LightChest" }, {3818625110U, "Z1" }, {3818830412U, "MinimumCost" }, {3821995487U, "MediumGloves" }, {3823379353U, "S4" }, {3823722273U, "AttackFRWidth" }, {3828799618U, "Skill" }, {3829211547U, "UnlockedAt" }, {3829640438U, "Condition_Group" }, {3831144414U, "ShieldPawn" }, {3831640960U, "UVAnimationFilename" }, {3833930352U, "GiantWorm" }, {3835973039U, "NodeName" }, {3839249358U, "AttackerResult" }, {3843671363U, "Hide" }, {3849507294U, "AttackExtra" }, {3851166947U, "UnlockNotification" }, {3851756701U, "PrecollisionModelName" }, {3851926318U, "FadeinTime" }, {3851938683U, "RenderBlurRadius" }, {3852881606U, "Areahighlight5" }, {3853219791U, "PauseTime" }, {3854292075U, "A10" }, {3857468364U, "Weapon4" }, {3860872062U, "Ammo" }, {3862538437U, "DwarfOffset" }, {3865063312U, "Warrior3" }, {3868453778U, "CodexPlot" }, {3869129205U, "Item" }, {3869319856U, "Effect_Float1" }, {3874293234U, "Den300ar_Elven_Alienage" }, {3876066832U, "Branch" }, {3876352629U, "Additive_VFX" }, {3876637093U, "Item7" }, {3878962831U, "Switch" }, {3882354086U, "String" }, {3883375756U, "DefaultModel" }, {3883708995U, "Ability1" }, {3885510726U, "Resist10" }, {3887359648U, "MaskFile" }, {3889806208U, "Weapon18" }, {3890253173U, "Skippable" }, {3890503361U, "Block" }, {3890651564U, "LookCenterAnimation" }, {3891682720U, "RepeatVar" }, {3891721707U, "ChanceToSpawn" }, {3892269670U, "TextureAnim" }, {3900260016U, "Material14" }, {3901905064U, "ShowUpdated" }, {3902822704U, "AttInit" }, {3910137788U, "DamageMod" }, {3910971971U, "ClassTable" }, {3915752458U, "CollisionModelName" }, {3918642513U, "State" }, {3922541164U, "ReqProp1Val" }, {3923340551U, "SoundFlying" }, {3926457399U, "TriggersTable" }, {3926984101U, "FullFace" }, {3927626024U, "Rogue3" }, {3928022310U, "FBloomHBlurWidth" }, {3928253333U, "ReqScale" }, {3928698813U, "Flags2" }, {3931411289U, "TacticPreset" }, {3938576008U, "AttackBR_Width" }, {3939967029U, "Special2" }, {3947417642U, "MovementTree" }, {3951357517U, "IsCodex" }, {3954156598U, "SubCommandLabel" }, {3954299140U, "Dead" }, {3958772845U, "SuicideDrone" }, {3961817308U, "SoundVariation" }, {3963006697U, "Resist21" }, {3963579354U, "Stone" }, {3964333308U, "TriggerCondPlot" }, {3973950146U, "AmbientAnim" }, {3973951270U, "MaulLevel" }, {3974246258U, "ShowInCharGen" }, {3975040547U, "ColorB" }, {3976007201U, "MassiveArmorLevel" }, {3979750556U, "TexFrame" }, {3979765386U, "AddBehavior" }, {3981703208U, "Slot6" }, {3982012617U, "MeleeRingOffset" }, {3982262343U, "Cir310ar_Fade_Burning_Tower" }, {3984976028U, "DonationMsgStrID" }, {3987022478U, "Weight3" }, {3988050111U, "Effect3_Float2" }, {3991628673U, "NStealthRank" }, {3992987874U, "AmbientTrack" }, {3996931316U, "Tag1" }, {4001205861U, "Material1" }, {4005536023U, "Eggman" }, {4005769326U, "Dmg_Param0" }, {4008755310U, "Highlight2" }, {4010074733U, "MaceLevel" }, {4014943936U, "EquipRules" }, {4016806506U, "FollowerBehavior" }, {4016958088U, "No_Props" }, {4020760148U, "TripsCounterTable" }, {4022271340U, "CameraDistance" }, {4023238248U, "ElementalDamage" }, {4023283012U, "DefaultAmmoVariation" }, {4024732903U, "ChanceAllToFail" }, {4026874824U, "PlotFlag" }, {4028046256U, "SmallIcon1" }, {4029050402U, "SuperSonicBall" }, {4030559806U, "Cost" }, {4032650538U, "Effect1_Int1" }, {4033394785U, "SoundImpactPitch" }, {4035217115U, "XPReward" }, {4035341531U, "DoTransition" }, {4035707095U, "XPValue" }, {4038846157U, "Count1" }, {4039116744U, "ShakeZFreq" }, {4039406263U, "Lot100ar_Lothering" }, {4040075570U, "AffectImmortal" }, {4040813163U, "Text" }, {4040874411U, "Above10_MainSystem" }, {4041832710U, "HP" }, {4041861912U, "AlbinoWasp" }, {4043451597U, "Den971ar_Franderel_Estate_2" }, {4044641107U, "CountRogue" }, {4045941194U, "Effect2_Duration" }, {4046337976U, "Y1" }, {4048885332U, "BCache" }, {4049735665U, "Material15" }, {4050457386U, "Effect_Label" }, {4057317829U, "React_VFX" }, {4064094881U, "ShowInPaperDoll" }, {4065552832U, "EntryIdx" }, {4066976339U, "Tint" }, {4068830396U, "NBonusPoints" }, {4073030320U, "TacticsTable" }, {4073552250U, "AvoidAOE" }, {4074452278U, "E1036" }, {4075059640U, "en-us" }, {4076986473U, "Rogue2" }, {4080270857U, "Script" }, {4083149655U, "InactiveFlag" }, {4084955326U, "RumbleBalance" }, {4086700450U, "HideWhenUndetected" }, {4086974314U, "Defend" }, {4091663077U, "ShakeRollFreq" }, {4095279793U, "CollisionUVAnimName" }, {4095623476U, "AreaListName" }, {4095975552U, "TriggerChance" }, {4096883099U, "ProjectileVFX" }, {4097169397U, "ShakeXFreq" }, {4098410857U, "Slot7" }, {4101564375U, "MovementSlide" }, {4103458417U, "Stature" }, {4103855738U, "Grit" }, {4105460571U, "TS_EquipmentChance" }, {4106097615U, "Weight2" }, {4110736530U, "BareHands" }, {4111007034U, "AttackBL" }, {4113407912U, "Resist20" }, {4113510532U, "DisplayMask" }, {4116951280U, "LargeCreature" }, {4117239826U, "DisplayType" }, {4124773871U, "FMoonScale" }, {4127988269U, "BaseDefenseBonus" }, {4130915854U, "Effect1" }, {4131661443U, "Conversation" }, {4132318421U, "GardenPositionZ" }, {4150543258U, "OnClick" }, {4152309341U, "InventoryLargeIcon" }, {4153844500U, "Herbalism_1" }, {4154413663U, "HostileAOE" }, {4158128431U, "Dmg_Param1" }, {4159435055U, "Highlight3" }, {4160861003U, "Enemy1" }, {4161236323U, "ArmorChest" }, {4165303809U, "Image" }, {4166442094U, "Movement3" }, {4170679821U, "AnimImpact" }, {4171920349U, "Length" }, {4174488590U, "CollisionDamage" }, {4175283712U, "AttackInescapable" }, {4175960391U, "Frequency_X" }, {4176180651U, "Sheath" }, {4183034357U, "CastAnim" }, {4184177456U, "Combo7" }, {4184355425U, "HeroBonus1" }, {4184436111U, "Loops3" }, {4186912019U, "Chance" }, {4190962293U, "StartWP" }, {4191282132U, "SnowPile" }, {4192749345U, "ArenaAnimation" }, {4194070896U, "Armor" }, {4198606075U, "Red" }, {4198879290U, "AttackBRWidth" }, {4200054996U, "Projectile_Secondary" }, {4201034125U, "ProjectileOffset" }, {4201640806U, "BootsModelVariation" }, {4204816209U, "BaseVolume" }, {4205337383U, "Abbreviation" }, {4208310877U, "GDAName" }, {4208995734U, "Animation_Override_Movement" }, {4211020504U, "S5" }, {4221383533U, "WaterSlide" }, {4224581544U, "ConversationTag" }, {4229539614U, "StrRef1" }, {4238402858U, "A11" }, {4238930973U, "RemoveAnimation" }, {4240277383U, "AreaHighlight4" }, {4243216356U, "Den961ar_Blood_Mage" }, {4243456048U, "FSaturation" }, {4244077197U, "Weapon5" }, {4247185583U, "BShowInPartyPicker" }, {4249357382U, "Acceleration" }, {4251534318U, "Rouge" }, {4252275623U, "RemoveSound" }, {4252583751U, "Den800ar_Aeonar" }, {4252948175U, "Charyb" }, {4253287381U, "ModelName" }, {4253838853U, "AmbientBlue" }, {4254176912U, "TopSpeed" }, {4255138574U, "PositionZ" }, {4260096281U, "KobeDragon" }, {4262197476U, "Item6" }, {4262380966U, "SpeedRotation" }, {4263868114U, "Comments" }, {4267385544U, "StrIDName" }, {4268196610U, "Ability0" }, {4269998343U, "Resist11" }, {4274162369U, "Weapon19" }, {4274380637U, "TalentID" }, {4276598643U, "Portrait" }, {4281463324U, "Cli900ar_Fort_Exterior" }, {4281518266U, "DerivdDescStrRef" }, {4282681231U, "List" }, {4286258897U, "Warrior2" }, {4286400462U, "WandLevel" }, {4289759885U, "ReactiveChance" }, {4290384881U, "Effect_Float0" }, {4290999015U, "TransitionTo" }, {4291291336U, "ActionCode" }, {4294307347U, "SoundMap" }, {4294575364U, "Orz570ar_Deeproad_Outskirts" }, {4294639615U, "CameraOffset" } }; const char *findGDAHeader(uint32 hash) { const GDAHeaderHash *header = Common::binarySearch(kGDAHeaderHashes, ARRAYSIZE(kGDAHeaderHashes), hash); if (!header) return 0; return header->value; } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/gdaheaders.h000066400000000000000000000021701331663051500205140ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Resolve a GDA column header hash back to its string. */ #ifndef AURORA_GDAHEADERS_H #define AURORA_GDAHEADERS_H #include "src/common/types.h" namespace Aurora { const char *findGDAHeader(uint32 hash); } // End of namespace Aurora #endif // AURORA_GDAHEADERS_H xoreos-tools-0.0.5/src/aurora/gff3file.cpp000066400000000000000000000530311331663051500204470ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling version V3.2/V3.3 of BioWare's GFFs (generic file format). */ /* See BioWare's own specs released for Neverwinter Nights modding * () */ #include #include "src/common/error.h" #include "src/common/memreadstream.h" #include "src/common/encoding.h" #include "src/common/ustring.h" #include "src/common/strutil.h" #include "src/aurora/gff3file.h" #include "src/aurora/util.h" #include "src/aurora/locstring.h" static const uint32 kVersion32 = MKTAG('V', '3', '.', '2'); static const uint32 kVersion33 = MKTAG('V', '3', '.', '3'); // Found in The Witcher, different language table namespace Aurora { GFF3File::Header::Header() { } void GFF3File::Header::read(Common::SeekableReadStream &gff3) { structOffset = gff3.readUint32LE(); structCount = gff3.readUint32LE(); fieldOffset = gff3.readUint32LE(); fieldCount = gff3.readUint32LE(); labelOffset = gff3.readUint32LE(); labelCount = gff3.readUint32LE(); fieldDataOffset = gff3.readUint32LE(); fieldDataCount = gff3.readUint32LE(); fieldIndicesOffset = gff3.readUint32LE(); fieldIndicesCount = gff3.readUint32LE(); listIndicesOffset = gff3.readUint32LE(); listIndicesCount = gff3.readUint32LE(); } GFF3File::GFF3File(Common::SeekableReadStream *gff3, uint32 id, bool repairNWNPremium) : _stream(gff3), _repairNWNPremium(repairNWNPremium), _offsetCorrection(0) { assert(_stream); load(id); } GFF3File::~GFF3File() { } uint32 GFF3File::getType() const { return _id; } const GFF3Struct &GFF3File::getTopLevel() const { return getStruct(0); } // --- Loader --- void GFF3File::load(uint32 id) { try { loadHeader(id); loadStructs(); loadLists(); } catch (Common::Exception &e) { e.add("Failed reading GFF3 file"); throw; } } void GFF3File::loadHeader(uint32 id) { if (_repairNWNPremium) { /* The GFF3 files in the encrypted premium module archive for Neverwinter * nights are deliberately broken: the file type and version have been * removed, and the offsets to the individual sections are increased * by a certain amount. * * This offset difference is calculated from the MD5 checksum of the * NWM file of the premium module. But since the first offset is a * known value, we can calculate the difference from there and don't * need to know the MD5 of the NWM file. */ uint32 firstOffset = _stream->readUint32LE(); uint32 maybeVersion = _stream->readUint32BE(); if ((maybeVersion != kVersion32) && (maybeVersion != kVersion33)) { if ((firstOffset >= 0x30) && (firstOffset <= 0x12F)) { // Yes, this looks like a messed-with GFF3 found in an NWN premium module _version = kVersion32; id = _id = 0xFFFFFFFF; _offsetCorrection = firstOffset - 0x30; } else // File is broken in a different way. The later checks will throw _repairNWNPremium = false; } else // This is not a GFF3 file that needs repairing _repairNWNPremium = false; _stream->seek(0); } if (!_repairNWNPremium) readHeader(*_stream); if ((id != 0xFFFFFFFF) && (_id != id)) throw Common::Exception("GFF3 has invalid ID (want %s, got %s)", Common::debugTag(id).c_str(), Common::debugTag(_id).c_str()); if ((_version != kVersion32) && (_version != kVersion33)) throw Common::Exception("Unsupported GFF3 file version %s", Common::debugTag(_version).c_str()); _header.read(*_stream); // Fix offsets in the header, and check for consistency if ((_header.structOffset < _offsetCorrection) || (_header.fieldOffset < _offsetCorrection) || (_header.labelOffset < _offsetCorrection) || (_header.fieldDataOffset < _offsetCorrection) || (_header.fieldIndicesOffset < _offsetCorrection) || (_header.listIndicesOffset < _offsetCorrection)) throw Common::Exception("GFF3 header broken: section offset smaller than offset correction"); _header.structOffset -= _offsetCorrection; _header.fieldOffset -= _offsetCorrection; _header.labelOffset -= _offsetCorrection; _header.fieldDataOffset -= _offsetCorrection; _header.fieldIndicesOffset -= _offsetCorrection; _header.listIndicesOffset -= _offsetCorrection; if ((_header.structOffset > _stream->size()) || (_header.fieldOffset > _stream->size()) || (_header.labelOffset > _stream->size()) || (_header.fieldDataOffset > _stream->size()) || (_header.fieldIndicesOffset > _stream->size()) || (_header.listIndicesOffset > _stream->size())) throw Common::Exception("GFF3 header broken: section offset points outside stream"); } void GFF3File::loadStructs() { static const uint32 kStructSize = 12; _structs.reserve(_header.structCount); for (uint32 i = 0; i < _header.structCount; i++) _structs.push_back(new GFF3Struct(*this, _header.structOffset + i * kStructSize)); } void GFF3File::loadLists() { /* Read in the lists section of the GFF3. * * GFF3s store lists in a linear fashion, with the indices prefixes by * the number of indices to follow. For example, with the indices counts * highlighted for better readability: * [3] 0 1 2 [5] 3 4 5 6 7 [1] 8 [2] 9 10 * This specifies 4 lists, with 3, 5, 1 and 2 entries, respectively. * The first list contains struct indices 0 to 2, the second 3 to 7, the * third 8 and the fourth 9 and 10. * * For easy handling, we convert this list into an array of struct * pointer arrays, and a small array to convert from an index into this * list of lists into a list index. */ _stream->seek(_header.listIndicesOffset); // Read list array std::vector rawLists; rawLists.resize(_header.listIndicesCount / 4); for (std::vector::iterator it = rawLists.begin(); it != rawLists.end(); ++it) *it = _stream->readUint32LE(); // Counting the actual amount of lists uint32 listCount = 0; for (size_t i = 0; i < rawLists.size(); i++) { uint32 n = rawLists[i]; if ((i + n) > rawLists.size()) throw Common::Exception("GFF3: List indices broken during counting"); i += n; listCount++; } _lists.resize(listCount); _listOffsetToIndex.resize(rawLists.size(), 0xFFFFFFFF); // Converting the raw list array into real, usable lists uint32 listIndex = 0; for (size_t i = 0; i < rawLists.size(); listIndex++) { _listOffsetToIndex[i] = listIndex; const uint32 n = rawLists[i++]; if ((i + n) > rawLists.size()) throw Common::Exception("GFF3: List indices broken during conversion"); _lists[listIndex].resize(n); for (uint32 j = 0; j < n; j++, i++) { const size_t structIndex = rawLists[i]; if (structIndex >= _structs.size()) throw Common::Exception("GFF3: List struct index out of range (%u >= %u)", (uint) structIndex, (uint) _structs.size()); _lists[listIndex][j] = _structs[structIndex]; } } } // --- Helpers for GFF3Struct --- const GFF3Struct &GFF3File::getStruct(uint32 i) const { if (i >= _structs.size()) throw Common::Exception("GFF3: Struct index out of range (%u >= %u)", i, (uint) _structs.size()); return *_structs[i]; } const GFF3List &GFF3File::getList(uint32 i) const { if (i >= _listOffsetToIndex.size()) throw Common::Exception("GFF3: List offset index out of range (%u >= %u)", i, (uint) _listOffsetToIndex.size()); const uint32 listIndex = _listOffsetToIndex[i]; if (listIndex == 0xFFFFFFFF) throw Common::Exception("GFF3: Empty list index at %u", i); assert(listIndex < _lists.size()); return _lists[listIndex]; } Common::SeekableReadStream &GFF3File::getStream(uint32 offset) const { _stream->seek(offset); return *_stream; } Common::SeekableReadStream &GFF3File::getFieldData() const { return getStream(_header.fieldDataOffset); } GFF3Struct::Field::Field() : type(kFieldTypeNone), data(0), extended(false) { } GFF3Struct::Field::Field(FieldType t, uint32 d) : type(t), data(d) { // These field types need extended field data extended = (type == kFieldTypeUint64 ) || (type == kFieldTypeSint64 ) || (type == kFieldTypeDouble ) || (type == kFieldTypeExoString ) || (type == kFieldTypeResRef ) || (type == kFieldTypeLocString ) || (type == kFieldTypeVoid ) || (type == kFieldTypeOrientation) || (type == kFieldTypeVector ) || (type == kFieldTypeStrRef ); } GFF3Struct::GFF3Struct(const GFF3File &parent, uint32 offset) : _parent(&parent) { load(offset); } GFF3Struct::~GFF3Struct() { } uint32 GFF3Struct::getID() const { return _id; } // --- Loader --- void GFF3Struct::load(uint32 offset) { Common::SeekableReadStream &data = _parent->getStream(offset); _id = data.readUint32LE(); _fieldIndex = data.readUint32LE(); _fieldCount = data.readUint32LE(); // Read the field(s) if (_fieldCount == 1) readField (data, _fieldIndex); else if (_fieldCount > 1) readFields(data, _fieldIndex, _fieldCount); } void GFF3Struct::readField(Common::SeekableReadStream &data, uint32 index) { // Sanity check if (index > _parent->_header.fieldCount) throw Common::Exception("GFF3: Field index out of range (%d/%d)", index, _parent->_header.fieldCount); // Seek data.seek(_parent->_header.fieldOffset + index * 12); // Read the field data const uint32 fieldType = data.readUint32LE(); const uint32 fieldLabel = data.readUint32LE(); const uint32 fieldData = data.readUint32LE(); // Read the name Common::UString fieldName = readLabel(data, fieldLabel); // And add the field to the map and name list _fields[fieldName] = Field((FieldType) fieldType, fieldData); _fieldNames.push_back(fieldName); } void GFF3Struct::readFields(Common::SeekableReadStream &data, uint32 index, uint32 count) { // Sanity check if (index > _parent->_header.fieldIndicesCount) throw Common::Exception("GFF3: Field indices index out of range (%d/%d)", index , _parent->_header.fieldIndicesCount); // Seek data.seek(_parent->_header.fieldIndicesOffset + index); // Read the field indices std::vector indices; readIndices(data, indices, count); // Read the fields for (std::vector::const_iterator i = indices.begin(); i != indices.end(); ++i) readField(data, *i); } void GFF3Struct::readIndices(Common::SeekableReadStream &data, std::vector &indices, uint32 count) const { indices.reserve(count); while (count-- > 0) indices.push_back(data.readUint32LE()); } Common::UString GFF3Struct::readLabel(Common::SeekableReadStream &data, uint32 index) const { data.seek(_parent->_header.labelOffset + index * 16); return Common::readStringFixed(data, Common::kEncodingASCII, 16); } Common::SeekableReadStream &GFF3Struct::getData(const Field &field) const { assert(field.extended); Common::SeekableReadStream &data = _parent->getFieldData(); data.skip(field.data); return data; } // --- Field properties --- size_t GFF3Struct::getFieldCount() const { return _fields.size(); } bool GFF3Struct::hasField(const Common::UString &field) const { return getField(field) != 0; } const std::vector &GFF3Struct::getFieldNames() const { return _fieldNames; } GFF3Struct::FieldType GFF3Struct::getFieldType(const Common::UString &field) const { const Field *f = getField(field); if (!f) return kFieldTypeNone; return f->type; } // --- Field value reader helpers --- const GFF3Struct::Field *GFF3Struct::getField(const Common::UString &name) const { FieldMap::const_iterator field = _fields.find(name); if (field == _fields.end()) return 0; return &field->second; } char GFF3Struct::getChar(const Common::UString &field, char def) const { const Field *f = getField(field); if (!f) return def; if (f->type != kFieldTypeChar) throw Common::Exception("GFF3: Field is not a char type"); return (char) f->data; } uint64 GFF3Struct::getUint(const Common::UString &field, uint64 def) const { const Field *f = getField(field); if (!f) return def; // Int types if (f->type == kFieldTypeByte) return (uint64) ((uint8 ) f->data); if (f->type == kFieldTypeUint16) return (uint64) ((uint16) f->data); if (f->type == kFieldTypeUint32) return (uint64) ((uint32) f->data); if (f->type == kFieldTypeChar) return (uint64) ((int64) ((int8 ) ((uint8 ) f->data))); if (f->type == kFieldTypeSint16) return (uint64) ((int64) ((int16) ((uint16) f->data))); if (f->type == kFieldTypeSint32) return (uint64) ((int64) ((int32) ((uint32) f->data))); if (f->type == kFieldTypeUint64) return (uint64) getData(*f).readUint64LE(); if (f->type == kFieldTypeSint64) return ( int64) getData(*f).readUint64LE(); // StrRef, a numerical reference to a string in a talk table if (f->type == kFieldTypeStrRef) { Common::SeekableReadStream &data = getData(*f); const uint32 size = data.readUint32LE(); if (size != 4) Common::Exception("StrRef field with invalid size (%d)", size); return (uint64) data.readUint32LE(); } throw Common::Exception("GFF3: Field is not an int type"); } int64 GFF3Struct::getSint(const Common::UString &field, int64 def) const { const Field *f = getField(field); if (!f) return def; // Int types if (f->type == kFieldTypeByte) return (int64) ((int8 ) ((uint8 ) f->data)); if (f->type == kFieldTypeUint16) return (int64) ((int16) ((uint16) f->data)); if (f->type == kFieldTypeUint32) return (int64) ((int32) ((uint32) f->data)); if (f->type == kFieldTypeChar) return (int64) ((int8 ) ((uint8 ) f->data)); if (f->type == kFieldTypeSint16) return (int64) ((int16) ((uint16) f->data)); if (f->type == kFieldTypeSint32) return (int64) ((int32) ((uint32) f->data)); if (f->type == kFieldTypeUint64) return (int64) getData(*f).readUint64LE(); if (f->type == kFieldTypeSint64) return (int64) getData(*f).readUint64LE(); // StrRef, a numerical reference to a string in a talk table if (f->type == kFieldTypeStrRef) { Common::SeekableReadStream &data = getData(*f); const uint32 size = data.readUint32LE(); if (size != 4) Common::Exception("GFF3: StrRef field with invalid size (%d)", size); return (int64) ((uint64) data.readUint32LE()); } throw Common::Exception("GFF3: Field is not an int type"); } bool GFF3Struct::getBool(const Common::UString &field, bool def) const { return getUint(field, def) != 0; } double GFF3Struct::getDouble(const Common::UString &field, double def) const { const Field *f = getField(field); if (!f) return def; if (f->type == kFieldTypeFloat) return convertIEEEFloat(f->data); if (f->type == kFieldTypeDouble) return getData(*f).readIEEEDoubleLE(); throw Common::Exception("GFF3: Field is not a double type"); } Common::UString GFF3Struct::getString(const Common::UString &field, const Common::UString &def) const { const Field *f = getField(field); if (!f) return def; // Direct string if (f->type == kFieldTypeExoString) { Common::SeekableReadStream &data = getData(*f); const uint32 length = data.readUint32LE(); return Common::readStringFixed(data, Common::kEncodingASCII, length); } // ResRef, resource reference, a shorter string if (f->type == kFieldTypeResRef) { /* In most games, this field has a limit of 16 characters, because * resource filenames were limited to 16 characters (without extension) * inside the archives. In Dragon Age: Origins and Dragon Age II, * however, this limit has been lifted, and a full 255 characters * are available in ResRef string fields. */ Common::SeekableReadStream &data = getData(*f); const uint32 length = data.readByte(); return Common::readStringFixed(data, Common::kEncodingASCII, length); } // LocString, a localized string if (f->type == kFieldTypeLocString) { LocString locString; getLocString(field, locString); return locString.getString(); } // Unsigned integer type, compose a string representation if ((f->type == kFieldTypeByte ) || (f->type == kFieldTypeUint16) || (f->type == kFieldTypeUint32) || (f->type == kFieldTypeUint64) || (f->type == kFieldTypeStrRef)) { return Common::composeString(getUint(field)); } // Signed integer type, compose a string representation if ((f->type == kFieldTypeChar ) || (f->type == kFieldTypeSint16) || (f->type == kFieldTypeSint32) || (f->type == kFieldTypeSint64)) { return Common::composeString(getSint(field)); } // Floating point type, compose a string representation if ((f->type == kFieldTypeFloat) || (f->type == kFieldTypeDouble)) { return Common::composeString(getDouble(field)); } // Vector, consisting of 3 floats if (f->type == kFieldTypeVector) { float x = 0.0, y = 0.0, z = 0.0; getVector(field, x, y, z); return Common::composeString(x) + "/" + Common::composeString(y) + "/" + Common::composeString(z); } // Orientation, consisting of 4 floats if (f->type == kFieldTypeOrientation) { float a = 0.0, b = 0.0, c = 0.0, d = 0.0; getOrientation(field, a, b, c, d); return Common::composeString(a) + "/" + Common::composeString(b) + "/" + Common::composeString(c) + "/" + Common::composeString(d); } throw Common::Exception("GFF3: Field is not a string(able) type"); } bool GFF3Struct::getLocString(const Common::UString &field, LocString &str) const { const Field *f = getField(field); if (!f || (f->type != kFieldTypeLocString)) return false; LocString locString; try { Common::SeekableReadStream &data = getData(*f); const uint32 size = data.readUint32LE(); Common::SeekableSubReadStream locStringData(&data, data.pos(), data.pos() + size); locString.readLocString(locStringData); } catch (...) { return false; } str.swap(locString); return true; } Common::SeekableReadStream *GFF3Struct::getData(const Common::UString &field) const { const Field *f = getField(field); if (!f) return 0; if ((f->type != kFieldTypeVoid) && (f->type != kFieldTypeExoString) && (f->type != kFieldTypeResRef)) throw Common::Exception("GFF3: Field is not a data type"); Common::SeekableReadStream &data = getData(*f); uint32 size = 0; if ((f->type == kFieldTypeVoid) || (f->type == kFieldTypeExoString)) size = data.readUint32LE(); else if ( f->type == kFieldTypeResRef) size = data.readByte(); else throw Common::Exception("GFF3: Field is not a data type"); return data.readStream(size); } void GFF3Struct::getVector(const Common::UString &field, float &x, float &y, float &z) const { const Field *f = getField(field); if (!f) return; if (f->type != kFieldTypeVector) throw Common::Exception("GFF3: Field is not a vector type"); Common::SeekableReadStream &data = getData(*f); x = data.readIEEEFloatLE(); y = data.readIEEEFloatLE(); z = data.readIEEEFloatLE(); } void GFF3Struct::getOrientation(const Common::UString &field, float &a, float &b, float &c, float &d) const { const Field *f = getField(field); if (!f) return; if (f->type != kFieldTypeOrientation) throw Common::Exception("GFF3: Field is not an orientation type"); Common::SeekableReadStream &data = getData(*f); a = data.readIEEEFloatLE(); b = data.readIEEEFloatLE(); c = data.readIEEEFloatLE(); d = data.readIEEEFloatLE(); } void GFF3Struct::getVector(const Common::UString &field, double &x, double &y, double &z) const { const Field *f = getField(field); if (!f) return; if (f->type != kFieldTypeVector) throw Common::Exception("GFF3: Field is not a vector type"); Common::SeekableReadStream &data = getData(*f); x = data.readIEEEFloatLE(); y = data.readIEEEFloatLE(); z = data.readIEEEFloatLE(); } void GFF3Struct::getOrientation(const Common::UString &field, double &a, double &b, double &c, double &d) const { const Field *f = getField(field); if (!f) return; if (f->type != kFieldTypeOrientation) throw Common::Exception("GFF3: Field is not an orientation type"); Common::SeekableReadStream &data = getData(*f); a = data.readIEEEFloatLE(); b = data.readIEEEFloatLE(); c = data.readIEEEFloatLE(); d = data.readIEEEFloatLE(); } // --- Struct reader --- const GFF3Struct &GFF3Struct::getStruct(const Common::UString &field) const { const Field *f = getField(field); if (!f) throw Common::Exception("GFF3: No such field"); if (f->type != kFieldTypeStruct) throw Common::Exception("GFF3: Field is not a struct type"); // Direct index into the struct array return _parent->getStruct(f->data); } // --- Struct list reader --- const GFF3List &GFF3Struct::getList(const Common::UString &field) const { const Field *f = getField(field); if (!f) throw Common::Exception("GFF3: No such field"); if (f->type != kFieldTypeList) throw Common::Exception("GFF3: Field is not a list type"); // Byte offset into the list area, all 32bit values. return _parent->getList(f->data / 4); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/gff3file.h000066400000000000000000000251041331663051500201140ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling version V3.2/V3.3 of BioWare's GFFs (generic file format). */ #ifndef AURORA_GFF3FILE_H #define AURORA_GFF3FILE_H #include #include #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/ptrvector.h" #include "src/common/ustring.h" #include "src/aurora/types.h" #include "src/aurora/aurorafile.h" namespace Common { class SeekableReadStream; } namespace Aurora { class LocString; class GFF3Struct; /** A GFF (generic file format) V3.2/V3.3 file, found in all Aurora games * except Sonic Chronicles: The Dark Brotherhood. Even games that have * V4.0/V4.1 GFFs additionally use V3.2/V3.3 files as well. * * GFF files store hierarchical data, similar in concept to XML. They are * used whenever such data is useful: to, for example, hold area and object * descriptions, module and campaign specifications or conversations. They * consist of a top-level struct, with a collection of fields of various * types, indexed by a human-readable string name. A field can then be * another struct (which itself will be a collection of fields) or a * list of structs, leading to a recursive, hierarchical structure. * * GFF V3.2/V3.3 files come in a multitude of types (ARE, DLG, ...), each * with its own 4-byte type ID ('ARE ', 'DLG ', ...). When specified in * the GFF3File constructor, the loader will enforce that it matches, and * throw an exception should it not. Conversely, an ID of 0xFFFFFFFF means * that no such type ID enforcement should be done. In both cases, the type * ID read from the file can get access through getType(). * * The GFF V3.2/V3.3 files found in the encrypted premium module archives * of Neverwinter Nights are deliberately broken in various way. When the * constructor parameter repairNWNPremium is set to true, GFF3File will * detect such broken files and automatically repair them. When this * parameter is set to false, no detection will take place, and these * broken files will lead the loader to throw an exception. * * There is no functional difference between GFF V3.2 and V3.3 files. GFF * V3.3 files exclusively appear in The Witcher (and every GFF file there * is of version V3.3), simply to denote that the language table used for * LocStrings is different. Since xoreos has more flexible handling of * language IDs anyway, this doesn't concern us. * * See also: GFF4File in gff4file.h for the later V4.0/V4.1 versions of * the GFF format. */ class GFF3File : boost::noncopyable, public AuroraFile { public: /** Take over this stream and read a GFF3 file out of it. */ GFF3File(Common::SeekableReadStream *gff3, uint32 id = 0xFFFFFFFF, bool repairNWNPremium = false); ~GFF3File(); /** Return the GFF3's specific type. */ uint32 getType() const; /** Returns the top-level struct. */ const GFF3Struct &getTopLevel() const; private: /** A GFF3 header. */ struct Header { uint32 structOffset; ///< Offset to the struct definitions. uint32 structCount; ///< Number of structs. uint32 fieldOffset; ///< Offset to the field definitions. uint32 fieldCount; ///< Number of fields. uint32 labelOffset; ///< Offset to the field labels. uint32 labelCount; ///< Number of labels. uint32 fieldDataOffset; ///< Offset to the field data. uint32 fieldDataCount; ///< Number of field data fields. uint32 fieldIndicesOffset; ///< Offset to the field indices. uint32 fieldIndicesCount; ///< Number of field indices. uint32 listIndicesOffset; ///< Offset to the list indices. uint32 listIndicesCount; ///< Number of list indices. Header(); void read(Common::SeekableReadStream &gff3); }; typedef Common::PtrVector StructArray; typedef std::vector ListArray; Common::ScopedPtr _stream; Header _header; ///< The GFF3's header. /** Should we try to read GFF3 files found in Neverwinter Nights premium modules? */ bool _repairNWNPremium; /** The correctional value for offsets to repair Neverwinter Nights premium modules. */ uint32 _offsetCorrection; StructArray _structs; ///< Our structs. ListArray _lists; ///< Our lists. /** To convert list offsets found in GFF3 to real indices. */ std::vector _listOffsetToIndex; // .--- Loading helpers void load(uint32 id); void loadHeader(uint32 id); void loadStructs(); void loadLists(); // '--- // .--- Helper methods called by GFF3Struct /** Return the GFF3 stream. */ Common::SeekableReadStream &getStream(uint32 offset) const; /** Return the GFF3 stream seeked to the start of the field data. */ Common::SeekableReadStream &getFieldData() const; /** Return a struct within the GFF3. */ const GFF3Struct &getStruct(uint32 i) const; /** Return a list within the GFF3. */ const GFF3List &getList (uint32 i) const; // '--- friend class GFF3Struct; }; /** A struct within a GFF3. */ class GFF3Struct { public: /** The type of a GFF3 field. */ enum FieldType { kFieldTypeNone = - 1, ///< Invalid type. kFieldTypeByte = 0, ///< A single byte. kFieldTypeChar = 1, ///< A single character. kFieldTypeUint16 = 2, ///< Unsigned 16bit integer. kFieldTypeSint16 = 3, ///< Signed 16bit integer. kFieldTypeUint32 = 4, ///< Unsigned 32bit integer. kFieldTypeSint32 = 5, ///< Signed 32bit integer. kFieldTypeUint64 = 6, ///< Unsigned 64bit integer. kFieldTypeSint64 = 7, ///< Signed 64bit integer. kFieldTypeFloat = 8, ///< IEEE float. kFieldTypeDouble = 9, ///< IEEE double. kFieldTypeExoString = 10, ///< String. kFieldTypeResRef = 11, ///< Resource reference, string. kFieldTypeLocString = 12, ///< Localized string. kFieldTypeVoid = 13, ///< Random data of variable length. kFieldTypeStruct = 14, ///< Struct containing a number of fields. kFieldTypeList = 15, ///< List containing a number of structs. kFieldTypeOrientation = 16, ///< An object orientation. kFieldTypeVector = 17, ///< A vector of 3 floats. kFieldTypeStrRef = 18 ///< String reference, index into a talk table. }; /** Return the struct's ID. * * The ID is a (non-unique) number that's saved in the GFF3 file. * It's sometimes used to identify the higher-level meaning of a struct * within a GFF3. * * The purpose of the ID in a GFF3 struct is comparable to the label in * a GFF4 struct. */ uint32 getID() const; /** Return the number of fields in this struct. */ size_t getFieldCount() const; /** Does this specific field exist? */ bool hasField(const Common::UString &field) const; /** Return a list of all field names in this struct. */ const std::vector &getFieldNames() const; /** Return the type of this field, or kFieldTypeNone if such a field doesn't exist. */ FieldType getFieldType(const Common::UString &field) const; // .--- Read field values char getChar(const Common::UString &field, char def = '\0' ) const; uint64 getUint(const Common::UString &field, uint64 def = 0 ) const; int64 getSint(const Common::UString &field, int64 def = 0 ) const; bool getBool(const Common::UString &field, bool def = false) const; double getDouble(const Common::UString &field, double def = 0.0) const; Common::UString getString(const Common::UString &field, const Common::UString &def = "") const; bool getLocString(const Common::UString &field, LocString &str) const; void getVector (const Common::UString &field, float &x, float &y, float &z ) const; void getOrientation(const Common::UString &field, float &a, float &b, float &c, float &d) const; void getVector (const Common::UString &field, double &x, double &y, double &z ) const; void getOrientation(const Common::UString &field, double &a, double &b, double &c, double &d) const; Common::SeekableReadStream *getData(const Common::UString &field) const; // '--- // .--- Structs and lists of structs const GFF3Struct &getStruct(const Common::UString &field) const; const GFF3List &getList (const Common::UString &field) const; // '--- private: /** A field in the GFF3 struct. */ struct Field { FieldType type; ///< Type of the field. uint32 data; ///< Data of the field. bool extended; ///< Does this field need extended data? Field(); Field(FieldType t, uint32 d); }; typedef std::map FieldMap; const GFF3File *_parent; ///< The parent GFF3. uint32 _id; ///< The struct's ID. uint32 _fieldIndex; ///< Field / Field indices index. uint32 _fieldCount; ///< Field count. FieldMap _fields; ///< The fields, indexed by their label. /** The names of all fields in this struct. */ std::vector _fieldNames; // .--- Loader GFF3Struct(const GFF3File &parent, uint32 offset); ~GFF3Struct(); void load(uint32 offset); void readField (Common::SeekableReadStream &data, uint32 index); void readFields (Common::SeekableReadStream &data, uint32 index, uint32 count); void readIndices(Common::SeekableReadStream &data, std::vector &indices, uint32 count) const; Common::UString readLabel(Common::SeekableReadStream &data, uint32 index) const; // '--- // .--- Field and field data accessors /** Returns the field with this tag. */ const Field *getField(const Common::UString &name) const; /** Returns the extended field data for this field. */ Common::SeekableReadStream &getData(const Field &field) const; // '--- friend class GFF3File; template friend void Common::DeallocatorDefault::destroy(T *); }; } // End of namespace Aurora #endif // AURORA_GFF3FILE_H xoreos-tools-0.0.5/src/aurora/gff4fields.h000066400000000000000000004721771331663051500204640ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * All currently known fields in V4.0/V4.1 GFFs. */ #ifndef AURORA_GFF4FIELDS_H #define AURORA_GFF4FIELDS_H namespace Aurora { namespace GFF4FieldNamesEnum { enum GFF4FieldNames { kGFF4Tag = 1, kGFF4Name = 2, kGFF4TemplateResRef = 3, kGFF4Position = 4, kGFF4Orientation = 5, kGFF4Uint8List = 6, kGFF4Int8List = 7, kGFF4Uint16List = 8, kGFF4Int16List = 9, kGFF4Uint32List = 10, kGFF4Int32List = 11, kGFF4Uint64List = 12, kGFF4Int64List = 13, kGFF4Float32List = 14, kGFF4Float64List = 15, kGFF4Vector3fList = 16, kGFF4Vector4fList = 17, kGFF4QuaternionfList = 18, kGFF4EcstringList = 19, kGFF4Color4fList = 20, kGFF4NameHash = 21, kGFF4Text = 22, kGFF4ObjectID = 23, kGFF4TsProperty = 900, kGFF4TsPropertyName = 901, kGFF4TsPropertyAtom = 902, kGFF4TsPropertyValue = 903, kGFF4TsPropertyChildren = 904, kGFF4TsPropertyVartype = 905, kGFF4ItemBaseID = 1000, kGFF4ItemCost = 1001, kGFF4ItemStackSize = 1002, kGFF4ItemStolen = 1003, kGFF4ItemPlot = 1004, kGFF4ItemIDentified = 1005, kGFF4ItemCharges = 1006, kGFF4ItemModelVariation = 1007, kGFF4ItemDescription = 1008, kGFF4ItemPropertyList = 1009, kGFF4ItemMaterial = 1010, kGFF4ItemAbilityID = 1011, kGFF4ItemAbilityPwr = 1012, kGFF4ItemProperties = 1013, kGFF4ItemPropertyPowers = 1014, kGFF4ItemPropertyEffectID = 1015, kGFF4ItemPropertyVFXID = 1018, kGFF4ItemSubitemsResRefs = 1019, kGFF4ItemCraftingRecipeID = 1020, kGFF4ItemBaseCost = 1021, kGFF4ItemPropParam1 = 2000, kGFF4ItemPropPropertyName = 2001, kGFF4ItemPropSubType = 2002, kGFF4ItemPropCostTable = 2003, kGFF4ItemPropCostValue = 2004, kGFF4ItemPropParam1Value = 2005, kGFF4ItemPropChanceAppear = 2006, kGFF4EnvWorld = 3000, kGFF4EnvWorldName = 3001, kGFF4EnvWorldAreaList = 3002, kGFF4LvlChildList = 3003, kGFF4LvlFileObjectVersion = 3004, kGFF4LvlChangeTime = 3005, kGFF4EnvArea = 3010, kGFF4EnvAreaID = 3011, kGFF4EnvAreaName = 3012, kGFF4EnvAreaFile = 3013, kGFF4EnvAreaEnvironmentSettings = 3014, kGFF4EnvAreaNavigationInfoFile = 3015, kGFF4EnvAreaRoomList = 3016, kGFF4EnvAreaRoomListElement = 3017, kGFF4EnvAreaPosition = 3018, kGFF4EnvAreaRotation = 3019, kGFF4EnvAreaPathfindExport = 3020, kGFF4EnvAreaPathfindVisInfo = 3021, kGFF4EnvAreaPathfindVisinfoCount = 3022, kGFF4EnvAreaFrameBufEffect = 3023, kGFF4EnvAreaCenter = 3024, kGFF4EnvAreaSkydomeModel = 3025, kGFF4EnvAreaFrameBufEffectList = 3026, kGFF4EnvAreaGlobalwindResRef = 3027, kGFF4EnvAreaLocalwindList = 3028, kGFF4EnvAreaPathfindCosts = 3029, kGFF4EnvRoom = 3030, kGFF4EnvRoomID = 3031, kGFF4EnvRoomName = 3032, kGFF4EnvRoomFile = 3033, kGFF4EnvRoomEnvironmentSettings = 3034, kGFF4EnvRoomPosition = 3035, kGFF4EnvRoomRotation = 3036, kGFF4EnvRoomPathfindGridSep = 3037, kGFF4EnvRoomPathfindCharHeight = 3038, kGFF4EnvRoomPathfindClearance = 3039, kGFF4EnvRoomPathfindExport = 3040, kGFF4EnvRoomPathfindVisInfo = 3041, kGFF4EnvRoomPathfindVisInfoCount = 3042, kGFF4EnvRoomPathGridFile = 3043, kGFF4EnvRoomPathConnectionList = 3044, kGFF4EnvRoomPathConnection = 3045, kGFF4EnvRoomPathConnectionID = 3046, kGFF4EnvRoomVisibilityList = 3047, kGFF4EnvRoomVisibility = 3048, kGFF4EnvRoomVisibilityID = 3049, kGFF4EnvRoomModelList = 3050, kGFF4EnvRoomLightList = 3051, kGFF4EnvRoomModelListElement = 3052, kGFF4EnvRoomLightListElement = 3053, kGFF4EnvRoomDynShadowDirection = 3054, kGFF4EnvRoomDynShadowEnabled = 3055, kGFF4EnvModelPathfindOverlapped = 3056, kGFF4EnvModelShowHighLod = 3057, kGFF4EnvModelSnapToTerrain = 3058, kGFF4EnvModelScale = 3059, kGFF4EnvModel = 3060, kGFF4EnvModelID = 3061, kGFF4EnvModelName = 3062, kGFF4EnvModelFile = 3063, kGFF4EnvModelPosition = 3064, kGFF4EnvModelRotation = 3065, kGFF4EnvModelPathfindNormal = 3066, kGFF4EnvLight = 3067, kGFF4EnvLightID = 3068, kGFF4EnvLightName = 3069, kGFF4EnvLightPosition = 3070, kGFF4EnvLightRotation = 3071, kGFF4LightColor = 3072, kGFF4LightIsDynamic = 3073, kGFF4LightType = 3074, kGFF4LightPointRadius = 3075, kGFF4LightColorMultiplier = 3076, kGFF4LightBaked = 3077, kGFF4LightEffect = 3078, kGFF4LightAffectDomain = 3079, kGFF4AreaGridNavInfo = 3080, kGFF4AreaGridRoomName = 3081, kGFF4AreaGridGridNavInfo = 3082, kGFF4AreaGridModelGrid = 3083, kGFF4AreaGridGridID = 3084, kGFF4AreaGridModelID = 3085, kGFF4AreaGridNbColumns = 3086, kGFF4AreaGridNbRows = 3087, kGFF4AreaGridCellSize = 3088, kGFF4AreaGridClearance = 3089, kGFF4AreaGridBasePos = 3090, kGFF4AreaGridNormal = 3091, kGFF4AreaGridData = 3092, kGFF4AreaGridHeight = 3093, kGFF4AreaGridAbstractSectorSize = 3094, kGFF4AreaGridAbstractSectors = 3095, kGFF4AreaGridAbstractMemory = 3096, kGFF4AreaGridID = 3097, kGFF4AreaGridCellID = 3098, kGFF4EnvRoomConnectivityList = 3099, kGFF4LightSpotInnerAngle = 3100, kGFF4LightSpotOuterAngle = 3101, kGFF4LightSpotDistance = 3102, kGFF4EnvLightProbe = 3103, kGFF4EnvLightProbeEnvMap = 3104, kGFF4EnvLightNumSamples = 3105, kGFF4EnvLightSize = 3106, kGFF4DynamicShadowVectorGame = 3107, kGFF4EnvLightProbeID = 3108, kGFF4EnvModelCutAwayOverride = 3109, kGFF4AreaGridArea = 3110, kGFF4AreaGridSoundData = 3114, kGFF4AreaGridAbstractionSNumReg = 3115, kGFF4AreaGridAbstractionSaddr = 3116, kGFF4AreaGridLightSubsetData8 = 3117, kGFF4AreaGridLightSubsetData16 = 3118, kGFF4LightCanBeOccluded = 3119, kGFF4AreaGridCellPadding = 3120, kGFF4AreaGridAreaID = 3111, kGFF4AreaGridRooms = 3112, kGFF4AreaGridRoom = 3113, kGFF4AreaGridRoomID = 3114, kGFF4AreaGridRoomNumberOfLinks = 3115, kGFF4AreaGridLinks = 3116, kGFF4AreaGridLink = 3117, kGFF4AreaGridLinkID = 3118, kGFF4AreaGridLinkCellID = 3119, kGFF4AreaGridLinkRoomID = 3120, kGFF4AreaGridLinkNeighborIDs = 3121, kGFF4EnvAreaChunkIsChunk = 3122, kGFF4EnvAreaChunkRowCount = 3123, kGFF4EnvAreaChunkColCount = 3124, kGFF4EnvAreaChunkWidth = 3125, kGFF4EnvAreaChunkHeight = 3126, kGFF4EnvAreaLayoutName = 3127, kGFF4EnvAreaStartPointName = 3128, kGFF4EnvAreaCutoffHeight = 3129, kGFF4LightAnimatedMinFrequency = 3130, kGFF4LightAnimatedMaxFrequency = 3131, kGFF4LightAnimatedMinIntensity = 3132, kGFF4LightAnimatedMaxIntensity = 3133, kGFF4EnvAreaCutoffSystemEnabled = 3134, kGFF4EnvMinimapTextureMapCoords = 3137, kGFF4EnvMinimapLowerLeftPoint = 3138, kGFF4EnvMinimapUpperRightPoint = 3139, kGFF4EnvRoomLowerLeftPoint = 3140, kGFF4EnvRoomUpperRightPoint = 3141, kGFF4EnvAreaForceCharacterLighting = 3142, kGFF4EnvAreaSunlightCanBeOccludedChar = 3148, kGFF4EnvAreaSunlightColorChar = 3149, kGFF4EnvAreaSunlightDirection = 3150, kGFF4EnvAreaSunlightEnabled = 3151, kGFF4EnvAreaSunlightColor = 3152, kGFF4EnvAreaSunlightColorMult = 3153, kGFF4TerrainChunk = 3154, kGFF4TerrainChunkList = 3155, kGFF4TerrainChunkCellPositionX = 3156, kGFF4TerrainChunkCellPositionY = 3157, kGFF4TerrainChunkLength = 3158, kGFF4TerrainChunkWidth = 3159, kGFF4TerrainChunkTexelSize = 3160, kGFF4TerrainChunkBlendpageSize = 3161, kGFF4TerrainChunkSectorID = 3162, kGFF4EnvAreaSunlightRotation = 3163, kGFF4EnvRoomLightVisList = 3164, kGFF4EnvFogColor = 3165, kGFF4EnvFogMaxDistance = 3166, kGFF4EnvFogMaxIntensity = 3167, kGFF4EnvFogEnabled = 3168, kGFF4EnvFogMinDistance = 3169, kGFF4EnvModelNameChanged = 3170, kGFF4EnvVegetation = 3171, kGFF4EnvCreature = 3172, kGFF4EnvCamera = 3200, kGFF4EnvCameraPivotDistance = 3201, kGFF4EnvStandalone = 3202, kGFF4EnvListArea = 3202, kGFF4EnvListRoom = 3203, kGFF4EnvListModel = 3204, kGFF4EnvListLight = 3205, kGFF4EnvPfContainerLayoutName = 3210, kGFF4EnvPfContainerExportData = 3211, kGFF4EnvPfContainerDataVersion = 3212, kGFF4EnvPfContainerVisInfo = 3213, kGFF4RimTreeRootNode = 3290, kGFF4RimTreeRimList = 3291, kGFF4RimTreeChildList = 3292, kGFF4RimTreeNodeTag = 3293, kGFF4RimTreeNodeResRef = 3294, kGFF4EnvGroup = 3300, kGFF4EnvGroupName = 3301, kGFF4EnvSpGroup = 3302, kGFF4EnvSpGroupName = 3303, kGFF4EnvSp = 3304, kGFF4EnvSpFile = 3305, kGFF4EnvObjectVisible = 3310, kGFF4EnvObjectLockSelection = 3311, kGFF4EnvModelInstanceID = 3320, kGFF4EnvModelBoundsCenter = 3321, kGFF4EnvModelBoundsRadius = 3322, kGFF4EnvModelLightmapAtlas = 3323, kGFF4EnvModelLightmapOffsetScale = 3324, kGFF4EnvModelLightmapPartID = 3235, kGFF4EnvModelLightmapAtlasList = 3326, kGFF4LvlLightmapSizeMultiplier = 3330, kGFF4LvlLightmapLastUpdatedList = 3331, kGFF4LvlLightmapLastUpdated = 3332, kGFF4LvlLightmapFilespec = 3333, kGFF4LvlLightingVersion = 3334, kGFF4LvlAoColorMin = 3340, kGFF4LvlAoColorMax = 3341, kGFF4LvlAoSamplesMin = 3342, kGFF4LvlAoSamplesMax = 3343, kGFF4LvlAoAdaptsampleEnabled = 3344, kGFF4LvlAoAdaptsampleAccuracy = 3345, kGFF4LvlAoAdaptsampleSmooth = 3346, kGFF4LvlAoConeAngle = 3347, kGFF4LvlAoMaxRayLength = 3348, kGFF4LvlAoExponent = 3349, kGFF4EnvTree = 3350, kGFF4EnvTreenodeID = 3351, kGFF4EnvTreeName = 3352, kGFF4EnvTreeFile = 3353, kGFF4EnvRoomTreenodeList = 3354, kGFF4EnvAreaTreecontrollerList = 3355, kGFF4EnvTreeScale = 3356, kGFF4EnvAreaTreecontrollerID = 3357, kGFF4EnvTreePaintedList = 3358, kGFF4EnvTreePaintedPosition = 3359, kGFF4EnvTreePaintedRotation = 3360, kGFF4EnvTreePaintedScale = 3361, kGFF4EnvScatterObjects = 3362, kGFF4EnvScatterObjectFile = 3363, kGFF4EnvScatterInstance = 3364, kGFF4EnvScatterInstanceList = 3365, kGFF4EnvScatterObjectList = 3366, kGFF4EnvScatterObjectID = 3367, kGFF4EnvScatterObjIgnoreMaxDensity = 3368, kGFF4EnvScatterObjMaxDensity = 3369, kGFF4EnvScatterObjMinScale = 3370, kGFF4EnvScatterObjMaxScale = 3371, kGFF4EnvScatterObjOrient = 3372, kGFF4EnvScatterObjPrototype = 3373, kGFF4EnvScatterObjMsiData = 3374, kGFF4EnvTreeColorTint = 3375, kGFF4EnvScatterobjSoundType = 3376, kGFF4EnvTreeColorLevelTint = 3377, kGFF4EnvTreeColorLevelIntensity = 3378, kGFF4EnvTreeDrawDistance = 3379, kGFF4TerrainExportArea = 3400, kGFF4TerrainExportAreaList = 3401, kGFF4TerrainAreaCellPositionX = 3403, kGFF4TerrainAreaCellPositionY = 3404, kGFF4TerrainAreaCellPositionZ = 3405, kGFF4TerrainAreaCellSizeX = 3406, kGFF4TerrainAreaCellSizeY = 3407, kGFF4TerrainAreaCellSizeZ = 3408, kGFF4TerrainAreaBorderCellWidth = 3409, kGFF4TerrainAreaVistaCellWidth = 3410, kGFF4TerrainAreaLightmapSize = 3411, kGFF4TerrainAreaLightmapSizeVista = 3412, kGFF4TerrainAreaSubdivideBy = 3413, kGFF4EnvModelPartGroup = 3500, kGFF4EnvModelLightmapOnly = 3501, kGFF4EnvModelLightmapFlag = 3502, kGFF4EnvModelExportFlag = 3503, kGFF4EnvModelDefaultAnimation = 3504, kGFF4EnvModelBlendTreeName = 3505, kGFF4EnvModelUserParamList = 3506, kGFF4EnvModelUserParamName = 3507, kGFF4EnvModelUserParamValue = 3508, kGFF4LvlWater = 3600, kGFF4LvlWaterSizeX = 3601, kGFF4LvlWaterSizeY = 3602, kGFF4LvlWaterMaxTessellation = 3603, kGFF4LvlWaterMeshID = 3604, kGFF4LvlWaterNormalMap = 3605, kGFF4LvlWaterHeightMap = 3606, kGFF4LvlWaterDeepColor = 3607, kGFF4LvlWaterShallowColor = 3608, kGFF4LvlWaterWaveFreq1 = 3609, kGFF4LvlWaterWaveAmpl1 = 3610, kGFF4LvlWaterWaveDirection1 = 3611, kGFF4LvlWaterWaveSpeed1 = 3618, kGFF4LvlWaterWaveFreq2 = 3612, kGFF4LvlWaterWaveAmpl2 = 3613, kGFF4LvlWaterWaveDirection2 = 3614, kGFF4LvlWaterWaveSpeed2 = 3619, kGFF4LvlWaterWaveFreq3 = 3615, kGFF4LvlWaterWaveAmpl3 = 3616, kGFF4LvlWaterWaveDirection3 = 3617, kGFF4LvlWaterWaveSpeed3 = 3620, kGFF4LvlWaterReflectivity = 3621, kGFF4LvlWaterFoamHeight = 3622, kGFF4LvlWaterSubdivDepthTolerance = 3623, kGFF4LvlWaterShallowDepth = 3624, kGFF4LvlWaterFoamColor = 3625, kGFF4LvlWaterWalkableDepth = 3626, kGFF4LvlWaterWallHeight = 3627, kGFF4LvlWaterOpacityFalloff = 3628, kGFF4LvlWaterSunlightSpecularPower = 3629, kGFF4LvlWaterSpecularMultiplier = 3630, kGFF4LvlWaterSpecularFalloff = 3631, kGFF4LvlWaterColorizeTransparency = 3632, kGFF4LvlWaterOverrideReflection = 3633, kGFF4LvlWaterEnableSpec = 3634, kGFF4LvlWind = 3700, kGFF4LvlWindID = 3701, kGFF4LvlWindName = 3702, kGFF4LvlWindIsGlobal = 3710, kGFF4LvlWindRegionRadius = 3711, kGFF4LvlWindRegionFalloff = 3712, kGFF4LvlWindSptStrength = 3713, kGFF4LvlWindSptGustMinPercent = 3714, kGFF4LvlWindSptGustMaxPercent = 3715, kGFF4LvlWindSptGustMinDuration = 3716, kGFF4LvlWindSptGustMaxDuration = 3717, kGFF4LvlWindSptBendAngle = 3718, kGFF4LvlWindClothResponse = 3719, kGFF4LvlWindClothResponseLmt = 3720, kGFF4LvlWindClothStrength = 3721, kGFF4LvlWindClothGustStrengthMin = 3722, kGFF4LvlWindClothGustStrengthMax = 3723, kGFF4LvlWindClothGustDurationMin = 3724, kGFF4LvlWindClothGustDurationMax = 3725, kGFF4LvlWindClothGustIntervalMin = 3726, kGFF4LvlWindClothGustIntervalMax = 3727, kGFF4LvlWindClothGustDirChange = 3728, kGFF4LvlWindClothGustAxisRatio = 3729, kGFF4LvlWindSptGustFrequency = 3730, kGFF4LvlCollisionWallInfo = 3730, kGFF4LvlCollisionWallVerticies = 3731, kGFF4LvlCollisionWallVerticiesV2 = 3732, kGFF4LvlMinimapPositionX = 3740, kGFF4LvlMinimapPositionY = 3741, kGFF4LvlMinimapSizeX = 3742, kGFF4LvlMinimapSizeY = 3743, kGFF4EnvStatPhys = 3744, kGFF4EnvStatPhysData = 3745, kGFF4LvlLightSubsetList = 3800, kGFF4LvlLightSubsetEntry = 3801, kGFF4LvlLightSubsetTotalEntries = 3802, kGFF4AnimationNodeName = 4000, kGFF4AnimationTarget = 4001, kGFF4AnimationSourceType = 4002, kGFF4AnimationElementsPerEntry = 4003, kGFF4AnimationNodeData = 4004, kGFF4AnimationNodeList = 4005, kGFF4AnimationName = 4006, kGFF4AnimationGeneralAnimName = 4007, kGFF4AnimationHasGobAnim = 4008, kGFF4AnimationAnimLength = 4009, kGFF4AnimationCombatRange = 4010, kGFF4AnimationIsAdditive = 4011, kGFF4AnimationIsOverride = 4012, kGFF4AnimationOverridePriority = 4013, kGFF4AnimationNameHash = 4014, kGFF4AnimationNodeNameHash = 4015, kGFF4AnimationEventTime = 4016, kGFF4AnimationEventID = 4017, kGFF4AnimationEventTarget = 4018, kGFF4AnimationEventString = 4019, kGFF4AnimationEventList = 4020, kGFF4AnimationTree = 4021, kGFF4AnimationTreeName = 4022, kGFF4AnimationTreeNode = 4023, kGFF4AnimationTreeNodeName = 4024, kGFF4AnimationTreeNodeFile = 4025, kGFF4AnimationTreeNodeWeight = 4026, kGFF4AnimationTreeNodeFlags = 4027, kGFF4AnimationTreeNodeFirstChild = 4028, kGFF4AnimationTreeNodeNumChildren = 4029, kGFF4AnimationTreeNodeParent = 4030, kGFF4AnimationBlendcurveAnimFrom = 4031, kGFF4AnimationBlendcurveAnimTo = 4032, kGFF4AnimationBlendcurveData = 4033, kGFF4AnimationBlendcurveList = 4034, kGFF4AnimationKeyTime = 4035, kGFF4AnimationKeyData0 = 4036, kGFF4AnimationKeyData1 = 4037, kGFF4AnimationKeyData2 = 4038, kGFF4AnimationKeyData3 = 4039, kGFF4AnimationIgnoreScale = 4040, kGFF4CutsceneRunTime = 5000, kGFF4CutsceneEndScript = 5001, kGFF4CutsceneLayout = 5002, kGFF4CutscenePosition = 5003, kGFF4CutsceneOrientation = 5004, kGFF4CutsceneTransitionTime = 5005, kGFF4CutsceneFov = 5006, kGFF4CutsceneBlendtree = 5007, kGFF4CutsceneAnimatic = 5008, kGFF4CutsceneShowAreaDynamics = 5009, kGFF4CutsceneStaged = 5010, kGFF4CutsceneLodCurves = 5011, kGFF4CutsceneAnimSoundEvents = 5012, kGFF4CutsceneEnableLevelFbes = 5013, kGFF4CutsceneLodOriginPos = 5014, kGFF4CutsceneLodOriginOri = 5015, kGFF4CutsceneFPS = 5016, kGFF4CutsceneStageResRef = 5017, kGFF4CutscenePlayUntilVoCompletes = 5018, kGFF4CutsceneAreaRequired = 5019, kGFF4CutsceneShadowRadius = 5020, kGFF4CutsceneLightOcclusion = 5021, kGFF4CutsceneHenchmanTag = 5050, kGFF4CutsceneHenchmanActions = 5051, kGFF4CutsceneResources = 5100, kGFF4CutsceneResourceResRef = 5101, kGFF4CutsceneResourceType = 5102, kGFF4CutsceneActors = 5200, kGFF4CutsceneActorID = 5201, kGFF4CutsceneActorModelResRef = 5202, kGFF4CutsceneActorDeprecated1 = 5203, kGFF4CutsceneActorDeprecated2 = 5204, kGFF4CutsceneActorDeprecated3 = 5205, kGFF4CutsceneActorActionQueue = 5206, kGFF4CutsceneActorDeprecated4 = 5207, kGFF4CutsceneActorCreatureResRef = 5208, kGFF4CutsceneActorCameraTarget = 5209, kGFF4CutsceneActorUsePose = 5210, kGFF4CutsceneActorPose = 5211, kGFF4CutsceneActorPoseSpeed = 5212, kGFF4CutsceneActorPoseHumanoid = 5213, kGFF4CutsceneActorOriginPos = 5214, kGFF4CutsceneActorOriginOri = 5215, kGFF4CutsceneActorMappingTag = 5216, kGFF4CutsceneActorInventory = 5217, kGFF4CutsceneActorTransitionDelay = 5218, kGFF4CutsceneActorPreviousPose = 5219, kGFF4CutsceneActorMappingRequired = 5220, kGFF4CutsceneActorFinalPos = 5221, kGFF4CutsceneActorFinalOri = 5222, kGFF4CutsceneActorMaster = 5223, kGFF4CutsceneActorLod = 5224, kGFF4CutsceneActorAmbientAnim = 5225, kGFF4CutsceneActorModelScale = 5226, kGFF4CutsceneActionType = 5300, kGFF4CutsceneActionStartTime = 5301, kGFF4CutsceneActionStopTime = 5302, kGFF4CutsceneActionCurves = 5303, kGFF4CutsceneActionCategory = 5304, kGFF4CutsceneActionCurveBaseValue = 5350, kGFF4CutsceneActionCurveVertices = 5351, kGFF4CutsceneActionCurveTransitions = 5352, kGFF4CutsceneActionCurveDeprecated = 5353, kGFF4CutsceneActionCurveVertexTime = 5370, kGFF4CutsceneActionCurveVertexValue = 5371, kGFF4CutsceneActionCurveTransType = 5380, kGFF4CutsceneActionCurveTransControl1 = 5381, kGFF4CutsceneActionCurveTransControl2 = 5382, kGFF4CutsceneActionAnimAnimationName = 5400, kGFF4CutsceneActionAnimBlendtreeName = 5401, kGFF4CutsceneActionAnimSpeed = 5402, kGFF4CutsceneActionAnimStartOffset = 5403, kGFF4CutsceneActionAnimDeprecated1 = 5404, kGFF4CutsceneActionAnimPlayGad = 5405, kGFF4CutsceneActionAnimPoseAnimation = 5406, kGFF4CutsceneActionAnimLinkToMovement = 5407, kGFF4CutsceneActionAnimGadKeysPos = 5408, kGFF4CutsceneActionAnimGadKeysOri = 5409, kGFF4CutsceneActionAnimBlendGad = 5410, kGFF4CutsceneActionAnimExtendGad = 5411, kGFF4CutsceneActionAnimLinkToMoveDist = 5412, kGFF4CutsceneActionAnimApplyFutureGads = 5413, kGFF4CutsceneActionFrameBufEffectFileName = 5520, kGFF4CutsceneActionFrameBufEffectEffectName = 5521, kGFF4CutsceneActionFrameBufEffectParamList = 5522, kGFF4CutsceneActionFrameBufEffectParamName = 5523, kGFF4CutsceneActionFrameBufEffectParamValue = 5524, kGFF4CutsceneActionFrameBufEffectParamCurveIndex = 5525, kGFF4CutsceneActionFrameBufEffectParamVectorIndex = 5526, kGFF4CutsceneActionSpeakLineLipsynchSet = 5562, kGFF4CutsceneActionSpeakLineVobank = 5563, kGFF4CutsceneActionSpeakLineFaHeadMove = 5564, kGFF4CutsceneActionSpeakLineNoVOIngame = 5565, kGFF4CutsceneActionStageCameraDefault = 5570, kGFF4CutsceneActionStageCameraHenchman = 5571, kGFF4CutsceneActionStagePlaceLookAt = 5580, kGFF4CutsceneActionShakeType = 5600, kGFF4CutsceneActionShakeDeprecated1 = 5601, kGFF4CutsceneActionShakeDeprecated2 = 5602, kGFF4CutsceneActionShakeNoiseSeed = 5603, kGFF4CutsceneActionShakeNoiseFrequency = 5604, kGFF4CutsceneActionShakeNoiseType = 5605, kGFF4CutsceneActionShakeNoiseCorrelated = 5606, kGFF4CutsceneActionShakeNoiseRoughness = 5607, kGFF4CutsceneActionShakeNoiseRampIn = 5608, kGFF4CutsceneActionShakeNoiseRampOut = 5609, kGFF4CutsceneActionActiveCameraActorID = 5610, kGFF4CutsceneActionHeadtrackTargetID = 5620, kGFF4CutsceneActionHeadtrackSpeed = 5621, kGFF4CutsceneActionHeadtrackDeprecated1 = 5624, kGFF4CutsceneActionHeadtrackDeprecated2 = 5625, kGFF4CutsceneActionHeadtrackDeprecated3 = 5626, kGFF4CutsceneActionHeadtrackDeprecated4 = 5627, kGFF4CutsceneActionHeadtrackRealignStart = 5628, kGFF4CutsceneActionHeadtrackRealignCont = 5629, kGFF4CutsceneActionLinkActorTargetID = 5630, kGFF4CutsceneActionLinkActorNodeID = 5631, kGFF4CutsceneActionLinkActorDeprecated1 = 5632, kGFF4CutsceneActionLinkActorDeprecated2 = 5633, kGFF4CutsceneActionLinkActorDeprecated3 = 5634, kGFF4CutsceneActionLinkActorDeprecated4 = 5635, kGFF4CutsceneActionLinkActorIsTargetCrust = 5636, kGFF4CutsceneActionLinkActorUseOffset = 5637, kGFF4CutsceneActionApplycrustTargetID = 5640, kGFF4CutsceneActionPoseAnimationPose = 5650, kGFF4CutsceneActionPoseAnimationAnimation = 5651, kGFF4CutsceneActionPoseAnimationLooping = 5652, kGFF4CutsceneActionPoseAnimationOutro = 5653, kGFF4CutsceneActionPoseAnimationOutroSpeed = 5654, kGFF4CutsceneActionSoundName = 5670, kGFF4CutsceneActionSoundSplineParamNo1 = 5671, kGFF4CutsceneActionSoundSplineParamNo2 = 5672, kGFF4CutsceneActionSoundSplineParamNo3 = 5673, kGFF4CutsceneActionSoundSplineParamNo4 = 5674, kGFF4CutsceneActionSoundSplineParamNo5 = 5675, kGFF4CutsceneActionChangeVisibilityVisible = 5680, kGFF4CutsceneActionToggleClothPhysics = 5700, kGFF4CutsceneActionToggleHairPhysics = 5701, kGFF4CutsceneActionSetLodDeprecated = 5720, kGFF4CutsceneActionDrawWeaponMain = 5730, kGFF4CutsceneActionDrawWeaponOff = 5731, kGFF4CutsceneActionPlayMovie = 5740, kGFF4CutsceneActionSetGore = 5750, kGFF4MMHName = 6000, kGFF4MMHMaterialObject = 6001, kGFF4MMHMaterialLibrary = 6002, kGFF4MMHResName = 6003, kGFF4MMHID = 6004, kGFF4MMHModelHierarchyModelDataName = 6005, kGFF4MMHMeshGroupName = 6006, kGFF4MMHNodePointLightColor = 6007, kGFF4MMHNodePointLightRadius = 6008, kGFF4MMHNodePointLightIsStatic = 6009, kGFF4MMHNodeAmbientLightColor = 6010, kGFF4MMHNodeEmitBirthRate = 6011, kGFF4MMHNodeEmitBirthRateRange = 6012, kGFF4MMHNodeEmitLife = 6013, kGFF4MMHNodeEmitLifeRange = 6014, kGFF4MMHNodeEmitScaleRange = 6015, kGFF4MMHNodeEmitInitialSpeed = 6016, kGFF4MMHNodeEmitInitialSpeedRange = 6017, kGFF4MMHNodeEmitAcceleration = 6018, kGFF4MMHNodeEmitInitialRotationSpeed = 6019, kGFF4MMHNodeEmitInitialRotationSpeedRange = 6020, kGFF4MMHNodeEmitRotationalAcceleration = 6021, kGFF4MMHNodeInvEmitterMovementSpreadUpdateDelay = 6022, kGFF4MMHNodeEmitSpawnSpreadX = 6023, kGFF4MMHNodeEmitSpawnSpreadY = 6024, kGFF4MMHNodeEmitMovementSpreadX = 6025, kGFF4MMHNodeEmitMovementSpreadY = 6026, kGFF4MMHNodeEmitOptionsBitflags = 6027, kGFF4MMHNodeEmitOptionsBirthrateInParticlesPerMeter = 6028, kGFF4MMHNodeEmitOptionsRandomInitialRotation = 6029, kGFF4MMHNodeEmitOptionsParticlesAffectedByWind = 6030, kGFF4MMHNodeEmitGravityMultiplier = 6031, kGFF4MMHNodeEmitOptionsParticlesFollowPath = 6032, kGFF4MMHNodeEmitOptionsLinkParticlesTogether = 6033, kGFF4MMHNodeEmitOptionsUpdateOnlyWhenVisible = 6034, kGFF4MMHNodeEmitOptionsEnableParticleCollisions = 6035, kGFF4MMHNodeEmitOptionsInheritVelocityInsteadOfPos = 6036, kGFF4MMHNodeEmitOrientationBehavior = 6037, kGFF4MMHNodeEmitParticleInheritance = 6038, kGFF4MMHNodeAgeMapCount = 6039, kGFF4MMHNodeAgeMapElementPercentLifeElapsed = 6040, kGFF4MMHNodeAgeMapElementScaleX = 6041, kGFF4MMHNodeAgeMapElementScaleY = 6042, kGFF4MMHNodeAgeMapElementColor = 6043, kGFF4MMHNodeSpawnVolumeOptionsBitflags = 6044, kGFF4MMHNodeSpawnVolumeOptionsSpawnWithinVolume = 6045, kGFF4MMHNodeSpawnVolumeOptionsInvertSpawnVolumeNorms = 6046, kGFF4MMHTranslation = 6047, kGFF4MMHRotation = 6048, kGFF4MMHAttributeName = 6049, kGFF4MMHAttributeSourceName = 6050, kGFF4MMHExportTagName = 6051, kGFF4MMHExportExportName = 6052, kGFF4MMHExportControllerType = 6053, kGFF4MMHBoundingBoxMin = 6054, kGFF4MMHBoundingBoxMax = 6055, kGFF4MMHNodeCollisionObjDensity = 6056, kGFF4MMHNodeCollisionObjType = 6057, kGFF4MMHShapeType = 6058, kGFF4MMHShapePmatName = 6059, kGFF4MMHShapeRotation = 6060, kGFF4MMHShapePosition = 6061, kGFF4MMHShapeCollisionMaskBitflags = 6062, kGFF4MMHShapeCollisionMaskAll = 6063, kGFF4MMHShapeCollisionMaskNone = 6064, kGFF4MMHShapeCollisionMaskItems = 6065, kGFF4MMHShapeCollisionMaskCreatures = 6066, kGFF4MMHShapeCollisionMaskPlaceables = 6067, kGFF4MMHShapeCollisionMaskTriggers = 6068, kGFF4MMHShapeCollisionMaskStaticGeometry = 6069, kGFF4MMHShapeCollisionMaskNonwalkable = 6070, kGFF4MMHShapeBoxDim = 6071, kGFF4MMHShapeRadius = 6072, kGFF4MMHShapeHeight = 6073, kGFF4MMHShapeMeshShapeFlags = 6074, kGFF4MMHShapeMeshHeightFieldAxis = 6075, kGFF4MMHShapeMeshHeightFieldExtent = 6076, kGFF4MMHShapeCookedDataStream = 6077, kGFF4MMHJointTarget = 6078, kGFF4MMHJointType = 6079, kGFF4MMHJointTypeStruct = 6080, kGFF4MMHJointLocalNormal1 = 6081, kGFF4MMHJointLocalNormal2 = 6082, kGFF4MMHJointLocalAnchor1 = 6083, kGFF4MMHJointLocalAnchor2 = 6084, kGFF4MMHJointLocalAxis1 = 6085, kGFF4MMHJointLocalAxis2 = 6086, kGFF4MMHJointMaxForce = 6087, kGFF4MMHJointMaxTorque = 6088, kGFF4MMHJointCollisionEnabled = 6089, kGFF4MMHJointSphericalSwingAxis = 6090, kGFF4MMHJointSphericalProjectionDistance = 6091, kGFF4MMHJointSphericalTwistLimitLow = 6092, kGFF4MMHJointSphericalTwistLimitHigh = 6093, kGFF4MMHJointSphericalSwingLimit = 6094, kGFF4MMHJointSphericalTwistSwing = 6095, kGFF4MMHJointSphericalSwingSpring = 6096, kGFF4MMHJointSphericalJointSpring = 6097, kGFF4MMHJointSphericalProjectionMode = 6098, kGFF4MMHJointSphericalSphereFlags = 6099, kGFF4MMHJointRevoluteLimitLow = 6100, kGFF4MMHJointRevoluteLimitHigh = 6101, kGFF4MMHJointRevoluteProjectionDistance = 6102, kGFF4MMHJointRevoluteProjectionAngle = 6103, kGFF4MMHJointRevoluteProjectionMode = 6104, kGFF4MMHJointRevoluteSpring = 6105, kGFF4MMHJointRevoluteMotorVelTarget = 6106, kGFF4MMHJointRevoluteMotorMaxForce = 6107, kGFF4MMHJointRevoluteMotorFreeSpin = 6108, kGFF4MMHJointRevoluteRevoluteFlags = 6109, kGFF4MMHJointDistanceMinDistance = 6110, kGFF4MMHJointDistanceMaxDistance = 6111, kGFF4MMHJointDistanceSpring = 6112, kGFF4MMHJointDistanceDistanceFlags = 6113, kGFF4MMHJointPulleyPulley1 = 6114, kGFF4MMHJointPulleyPulley2 = 6115, kGFF4MMHJointPulleyDistance = 6116, kGFF4MMHJointPulleyStiffness = 6117, kGFF4MMHJointPulleyRatio = 6118, kGFF4MMHJointPulleyMotorVelTarget = 6119, kGFF4MMHJointPulleyMotorMaxForce = 6120, kGFF4MMHJointPulleyMotorFreeSpin = 6121, kGFF4MMHJointPulleyPulleyFlags = 6122, kGFF4MMHJoint6dofXMotion = 6123, kGFF4MMHJoint6dofYMotion = 6124, kGFF4MMHJoint6dofZMotion = 6125, kGFF4MMHJoint6dofSwing1Motion = 6126, kGFF4MMHJoint6dofSwing2Motion = 6127, kGFF4MMHJoint6dofTwistMotion = 6128, kGFF4MMHJoint6dofLinearLimit = 6129, kGFF4MMHJoint6dofSwing1Limit = 6130, kGFF4MMHJoint6dofSwing2Limit = 6131, kGFF4MMHJoint6dofTwistLimitLow = 6132, kGFF4MMHJoint6dofTwistLimitHigh = 6133, kGFF4MMHJoint6dofDriveOrientation = 6134, kGFF4MMHJoint6dofDriveXDriveType = 6135, kGFF4MMHJoint6dofDriveXDriveSpring = 6136, kGFF4MMHJoint6dofDriveXDriveDamping = 6137, kGFF4MMHJoint6dofDriveXDriveForceLimit = 6138, kGFF4MMHJoint6dofDriveYDriveType = 6139, kGFF4MMHJoint6dofDriveYDriveSpring = 6140, kGFF4MMHJoint6dofDriveYDriveDamping = 6141, kGFF4MMHJoint6dofDriveYDriveForceLimit = 6142, kGFF4MMHJoint6dofDriveZDriveType = 6143, kGFF4MMHJoint6dofDriveZDriveSpring = 6144, kGFF4MMHJoint6dofDriveZDriveDamping = 6145, kGFF4MMHJoint6dofDriveZDriveForceLimit = 6146, kGFF4MMHJoint6dofDriveSwingDriveType = 6147, kGFF4MMHJoint6dofDriveSwingDriveSpring = 6148, kGFF4MMHJoint6dofDriveSwingDriveDamping = 6149, kGFF4MMHJoint6dofDriveSwingDriveForceLimit = 6150, kGFF4MMHJoint6dofDriveTwistDriveType = 6151, kGFF4MMHJoint6dofDriveTwistDriveSpring = 6152, kGFF4MMHJoint6dofDriveTwistDriveDamping = 6153, kGFF4MMHJoint6dofDriveTwistDriveForceLimit = 6154, kGFF4MMHJoint6dofDriveSlerpDriveType = 6155, kGFF4MMHJoint6dofDriveSlerpDriveSpring = 6156, kGFF4MMHJoint6dofDriveSlerpDriveDamping = 6157, kGFF4MMHJoint6dofDriveSlerpDriveForceLimit = 6158, kGFF4MMHJoint6dofDrivePosition = 6159, kGFF4MMHJoint6dofDriveLinearVelocity = 6160, kGFF4MMHJoint6dofDriveAngularVelocity = 6161, kGFF4MMHJoint6dofProjectionDistance = 6162, kGFF4MMHJoint6dofProjectionAngle = 6163, kGFF4MMHJoint6dofGearRatio = 6164, kGFF4MMHJoint6dofProjectionMode = 6165, kGFF4MMHJoint6dofD6Flags = 6166, kGFF4MMHDataSemantic = 6167, kGFF4MMHDataIsIndexStream = 6168, kGFF4MMHDataType = 6169, kGFF4MMHDataBitflags = 6170, kGFF4MMHDataLooping = 6171, kGFF4MMHDataInstanced = 6172, kGFF4MMHDataCount = 6173, kGFF4MMHDataPrimitiveType = 6174, kGFF4MMHDataFrequency = 6175, kGFF4MMHMeshCastRuntimeShadow = 6176, kGFF4MMHMeshCastBakedShadow = 6177, kGFF4MMHShapeCollisionMaskEffects = 6178, kGFF4MMHShapeCollisionMaskWaypoints = 6179, kGFF4MMHFlipbookFramesPerSecond = 6180, kGFF4MMHFlipbookRows = 6181, kGFF4MMHFlipbookColumns = 6182, kGFF4MMHFlipbookRandomStartFrame = 6183, kGFF4MMHEmitterTargetName = 6184, kGFF4MMHEmitterTargetAttraction = 6185, kGFF4MMHEmitterTargetRadius = 6186, kGFF4MMHEmitterSpawnDirectionTracksTarget = 6187, kGFF4MMHEmitterKillParticleWhenTargetHit = 6188, kGFF4MMHEmitterFlipbookType = 6189, kGFF4MMHLightprobeIrradianceCoefficientsRed = 6190, kGFF4MMHLightprobeIrradianceCoefficientsGreen = 6191, kGFF4MMHLightprobeIrradianceCoefficientsBlue = 6192, kGFF4MMHMeshCutAway = 6193, kGFF4MMHMeshPunchThrough = 6194, kGFF4MMHClothThickness = 6195, kGFF4MMHClothDensity = 6196, kGFF4MMHClothBendingStiffness = 6197, kGFF4MMHClothStretchingStiffness = 6198, kGFF4MMHClothDampingCoefficient = 6199, kGFF4MMHClothFriction = 6200, kGFF4MMHClothPressure = 6201, kGFF4MMHClothTearFactor = 6202, kGFF4MMHClothCollisionResponseCoefficient = 6203, kGFF4MMHClothAttachmentResponseCoefficient = 6204, kGFF4MMHClothAttachmentTearFactor = 6205, kGFF4MMHClothSolverIterations = 6206, kGFF4MMHClothExternalAcceleration = 6207, kGFF4MMHClothWakeUpCounter = 6208, kGFF4MMHClothSleepLinearVelocity = 6209, kGFF4MMHClothFlagBitflags = 6210, kGFF4MMHClothFlagPressure = 6211, kGFF4MMHClothFlagStatic = 6212, kGFF4MMHClothFlagDisableCollision = 6213, kGFF4MMHClothFlagSelfcollision = 6214, kGFF4MMHClothFlagVisualization = 6215, kGFF4MMHClothFlagGravity = 6216, kGFF4MMHClothFlagBending = 6217, kGFF4MMHClothFlagBendingOrtho = 6218, kGFF4MMHClothFlagDamping = 6219, kGFF4MMHClothFlagCollisionTwoway = 6220, kGFF4MMHClothFlagTriangleCollision = 6221, kGFF4MMHClothFlagTearable = 6222, kGFF4MMHClothFlagHardware = 6223, kGFF4MMHClothFlagComdamping = 6224, kGFF4MMHClothAttachmentType = 6225, kGFF4MMHClothAttachmentFlagBitflags = 6226, kGFF4MMHClothAttachmentFlagTwoWayAttachment = 6227, kGFF4MMHClothAttachmentFlagTearableAttachment = 6228, kGFF4MMHClothAttachmentShapeName = 6229, kGFF4MMHClothAttachmentVertexID = 6230, kGFF4MMHClothAttachmentLocalPos = 6231, kGFF4MMHClothCookedDataStream = 6232, kGFF4MMHClothMeshGroupStruct = 6233, kGFF4MMHNodeEmitType = 6234, kGFF4MMHNodeCrustHookID = 6235, kGFF4MMHCollisionObjectVolume = 6236, kGFF4MMHObjectVolume = 6237, kGFF4MMHExportTagVariableType = 6238, kGFF4MMHEmitterIsPhysicsEmitter = 6239, kGFF4MMHShapeVolume = 6240, kGFF4MMHShapeName = 6241, kGFF4MMHSnapPosition = 6242, kGFF4MMHEmitterIsPhysicsObjectSpawnEmitter = 6243, kGFF4MMHShapeAllowEmitterSpawn = 6244, kGFF4MMHCollisionGroup = 6245, kGFF4MMHEmitterEmitterAttachmentType = 6246, kGFF4MMHEmitterEmitterAttachmentName = 6247, kGFF4MMHFacialAnimationBlueprintName = 6248, kGFF4MMHNodePointLightIntensityVariation = 6249, kGFF4MMHNodePointLightIntensityPeriod = 6250, kGFF4MMHNodePointLightIntensityPeriodDelta = 6251, kGFF4MMHShapeFadeable = 6252, kGFF4MMHLightprobeIrradianceRes = 6253, kGFF4MMHBoneIndex = 6254, kGFF4MMHMeshBonesUsed = 6255, kGFF4MMHTotalBones = 6256, kGFF4MMHClothWindEnabled = 6257, kGFF4MMHClothWindSpace = 6258, kGFF4MMHClothWindDirection = 6259, kGFF4MMHClothWindResponse = 6260, kGFF4MMHClothWindResponseLimit = 6261, kGFF4MMHClothWindStrength = 6262, kGFF4MMHClothWindGustMinStrength = 6263, kGFF4MMHClothWindGustMaxStrength = 6264, kGFF4MMHClothWindGustMinDuration = 6265, kGFF4MMHClothWindGustMaxDuration = 6266, kGFF4MMHClothWindGustMinInterval = 6267, kGFF4MMHClothWindGustMaxInterval = 6268, kGFF4MMHClothWindGustDirChange = 6269, kGFF4MMHClothWindGustAxisRatio = 6270, kGFF4MMHClothWindSpeedtreeUpdateTime = 6271, kGFF4MMHClothWindSpeedtreeStrength = 6272, kGFF4MMHClothWindSpeedtreeDirection = 6273, kGFF4MMHExportControllerIndex = 6274, kGFF4MMHTotalExports = 6275, kGFF4MMHClothWindSpeedtreeParams = 6276, kGFF4MMHShapeCollisionMaskWater = 6277, kGFF4MMHScale = 6278, kGFF4MMHNodeEmitAgemapColorMultiplier = 6279, kGFF4MMHNodeEmitAgemapScalexMultiplier = 6280, kGFF4MMHNodeEmitAgemapScaleyMultiplier = 6281, kGFF4MMHNodeEmitOptionsBounciness = 6282, kGFF4MMHNodeEmitOptionsFriction = 6283, kGFF4MMHNodeEmitMeshParticleModelName = 6284, kGFF4MMHNodeSpawnVolumeType = 6285, kGFF4MMHNodeSpawnVolumeRadius = 6286, kGFF4MMHNodeSpawnVolumeCylinderLength = 6287, kGFF4MMHNodeSpawnVolumeCylinderAxis = 6288, kGFF4MMHNodeSpawnVolumeBoxMin = 6289, kGFF4MMHNodeSpawnVolumeBoxMax = 6290, kGFF4MMHNodeSpawnVolumeOptionsNormalsAsDirection = 6291, kGFF4MMHWeapontrailSegmentLength = 6292, kGFF4MMHWeapontrailDuration = 6293, kGFF4MMHNodeEmitWorldAxisAcceleration = 6294, kGFF4MMHShapeCollisionMaskTerrainWall = 6295, kGFF4MMHNodeLightAffectDomain = 6296, kGFF4MmnNodeEmitVertexFormat = 6297, kGFF4MMHNodeEmitOptionsObjectSpaceAcceleration = 6298, kGFF4MMHNodeEmitInitialRotation = 6299, kGFF4MMHNodeEmitInitialRotationRange = 6300, kGFF4MMHMeshReceiveBakedShadow = 6301, kGFF4MMHNodeEmitMeshParticleUpAxis = 6302, kGFF4MMHNodeEmitMeshParticleRollAxis = 6303, kGFF4MMHMeshReceiveRuntimeShadow = 6304, kGFF4MMHShapeCollisionMaskWalkable = 6305, kGFF4MMHModelMeshNameList = 6306, kGFF4MMHNodeMeshName = 6307, kGFF4MMHNodeEmitUvDistributionSize = 6308, kGFF4MMHNodeEmitIgnoreDistortion = 6309, kGFF4MMHNodeEmitSplatParamsWidth = 6310, kGFF4MMHNodeEmitSplatParamsHeight = 6311, kGFF4MMHNodeEmitSplatParamsNumsamplesWidth = 6312, kGFF4MMHNodeEmitSplatParamsNumsamplesHeight = 6313, kGFF4MMHNodeEmitSplatParamsOrientationRange = 6314, kGFF4MMHNodeEmitSplatParamsLife = 6315, kGFF4MMHNodeEmitSplatParamsFlipbookType = 6316, kGFF4MMHNodeEmitSplatParamsFlipbookFramesPerSecond = 6317, kGFF4MMHNodeEmitSplatParamsFlipbookRows = 6318, kGFF4MMHNodeEmitSplatParamsFlipbookColumns = 6319, kGFF4MMHNodeEmitSplatParamsFlipbookRandomStartFrame = 6320, kGFF4MMHNodeEmitCanParticlesSplat = 6321, kGFF4MMHNodeEmitSplatParamsAgeMapElemPercLifeElapsed = 6322, kGFF4MMHNodeEmitLod = 6323, kGFF4MMHNodeEmitSplatParamsMaterialName = 6324, kGFF4MMHNodeEmitUserParamName = 6325, kGFF4MMHRemoteMaterialDecalName = 6327, kGFF4MMHRemoteMaterialFresnelFalloff = 6328, kGFF4MMHRemoteMaterialInvertFresnel = 6329, kGFF4MMHNodeSoundMaterial = 6330, kGFF4MMHRemoteMaterialAlpha = 6331, kGFF4MMHRemoteMaterialTint = 6332, kGFF4MMHEmitterPresimulateTime = 6333, kGFF4MMHMeshIsVFXMesh = 6334, kGFF4MMHMeshMaterialColor = 6335, kGFF4MMHLightProbeIrradianceRed = 6336, kGFF4MMHLightProbeIrradianceGreen = 6337, kGFF4MMHLightProbeIrradianceBlue = 6338, kGFF4MMHLightCanBeOccluded = 6339, kGFF4MMHUseVariationTint = 6340, kGFF4MMHNodeEmitSplatparamsHoldLastFrame = 6341, kGFF4MMHEmitterEmitterAttachmentSpawnOnSurface = 6342, kGFF4MMHEmitterEmitterAttachmentUseNormalForVelocity = 6343, kGFF4MMHNodeEmitSplatparamsAgemapColorMultiplier = 6344, kGFF4MMHNodeLightVersion = 6345, kGFF4MMHMeshDefaultHidden = 6346, kGFF4MMHShapeTypeStruct = 6998, kGFF4MMHChildren = 6999, kGFF4TerrainVersion = 7000, kGFF4TerrainBaseRows = 7001, kGFF4TerrainBaseColumns = 7002, kGFF4TerrainLengthUnits = 7003, kGFF4TerrainWidthUnits = 7004, kGFF4TerrainSectorRows = 7005, kGFF4TerrainSectorColumns = 7006, kGFF4TerrainTessellation = 7007, kGFF4TerrainSectorID = 7008, kGFF4TerrainSectorList = 7009, kGFF4TerrainMeshFaceID = 7010, kGFF4TerrainMeshFaceList = 7011, kGFF4TerrainMeshEdgeID = 7012, kGFF4TerrainMeshEdgeStartVertex = 7013, kGFF4TerrainMeshEdgeBoundaryFlag = 7014, kGFF4TerrainMeshEdgeSubedgeList = 7015, kGFF4TerrainMeshEdgeList = 7016, kGFF4TerrainSubEdgeID = 7017, kGFF4TerrainMeshVertexID = 7018, kGFF4TerrainMeshVertexPosition = 7019, kGFF4TerrainMeshVertexLevel = 7020, kGFF4TerrainMeshVertexConstraintList = 7021, kGFF4TerrainMeshVertexConstraintID = 7022, kGFF4TerrainMeshVertexList = 7023, kGFF4TerrainElementIDValue = 7024, kGFF4TerrainElementIDSector = 7025, kGFF4TerrainMaterialValue = 7026, kGFF4TerrainMaterialList = 7027, kGFF4TerrainAreaInformation = 7028, kGFF4TerrainVertexU = 7029, kGFF4TerrainVertexV = 7030, kGFF4TerrainMaskDataWidth = 7031, kGFF4TerrainMaskDataHeight = 7032, kGFF4TerrainMaskDataStride = 7033, kGFF4TerrainMaskDataArray = 7034, kGFF4TerrainVMaskData = 7035, kGFF4TerrainAMaskData = 7036, kGFF4TerrainMapVertexID = 7037, kGFF4TerrainMapVertexUVW = 7038, kGFF4TerrainMapVertexList = 7039, kGFF4TerrainMapEdgeID = 7040, kGFF4TerrainMapEdgeStartVertex = 7041, kGFF4TerrainMapEdgeList = 7042, kGFF4TerrainMapFaceID = 7043, kGFF4TerrainMapFaceLayer = 7044, kGFF4TerrainMapFaceList = 7045, kGFF4TerrainMapFaceBlendPageID = 7046, kGFF4TerrainBlendWeightMatID = 7047, kGFF4TerrainBlendWeightWeight = 7048, kGFF4TerrainBlendTexelWeightList = 7049, kGFF4TerrainBlendPageID = 7050, kGFF4TerrainBlendPageWidth = 7051, kGFF4TerrainBlendPageHeight = 7052, kGFF4TerrainBlendPageTexelList = 7053, kGFF4TerrainBlendPageList = 7054, kGFF4TerrainMesh = 7055, kGFF4TerrainPalette = 7056, kGFF4TerrainBlendTexelByteWeightList = 7057, kGFF4TerrainMeshName = 7058, kGFF4TerrainPaletteName = 7059, kGFF4TerrainMaterial = 7060, kGFF4TerrainMaterialID = 7061, kGFF4TerrainMaterialName = 7062, kGFF4TerrainMaterialScale = 7063, kGFF4TerrainMaterialDiffuseName = 7064, kGFF4TerrainMaterialNormalName = 7065, kGFF4TerrainMaterialSpecualarName = 7066, kGFF4TerrainMaterialHeightMapName = 7067, kGFF4TerrainPaletteParallaxGlobal = 7068, kGFF4TerrainMaterialReliefScale = 7069, kGFF4TerrainBlendTexel6ByteWeightList = 7070, kGFF4TerrainMeshVertexConstraintA = 7071, kGFF4TerrainMeshVertexConstraintB = 7072, kGFF4TerrainMeshEdgeSubEdgeA = 7073, kGFF4TerrainMeshEdgeSubEdgeB = 7074, kGFF4TerrainBlendTexelID = 7075, kGFF4TerrainSoundData = 7076, kGFF4TerrainMaterialSpecularColor = 7077, kGFF4WaterInformation = 7900, kGFF4WaterVersion = 7901, kGFF4WaterID = 7902, kGFF4WaterVertexList = 7903, kGFF4WaterVertexPosition = 7904, kGFF4WaterVertexNormal = 7905, kGFF4WaterVertexUVW = 7906, kGFF4WaterVertexColor = 7907, kGFF4WaterVertexIndexList = 7908, kGFF4MeshChunkVertexSize = 8000, kGFF4MeshChunkVertexCount = 8001, kGFF4MeshChunkIndexCount = 8002, kGFF4MeshChunkPrimitiveType = 8003, kGFF4MeshChunkIndexFormat = 8004, kGFF4MeshChunkBaseVertexIndex = 8005, kGFF4MeshChunkVertexOffset = 8006, kGFF4MeshChunkMinIndex = 8007, kGFF4MeshChunkVerticesReferenced = 8008, kGFF4MeshChunkStartIndex = 8009, kGFF4MeshChunkHasInstGeom = 8010, kGFF4MeshChunkAdditionalStreams = 8011, kGFF4MeshStreamVertexSize = 8012, kGFF4MeshStreamVertexCount = 8013, kGFF4MeshStreamFrequency = 8014, kGFF4MeshStreamLooping = 8015, kGFF4MeshStreamInstanced = 8016, kGFF4MeshBoundsBoxMin = 8017, kGFF4MeshBoundsBoxMax = 8018, kGFF4MeshBoundsSphere = 8019, kGFF4MeshChunkBounds = 8020, kGFF4MeshChunks = 8021, kGFF4MeshVertexData = 8022, kGFF4MeshIndexData = 8023, kGFF4MeshStreamVertexData = 8024, kGFF4MeshChunkVertexDeclarator = 8025, kGFF4MeshVertexDeclaratorStream = 8026, kGFF4MeshVertexDeclaratorOffset = 8027, kGFF4MeshVertexDeclaratorDatatype = 8028, kGFF4MeshVertexDeclaratorUsage = 8029, kGFF4MeshVertexDeclaratorUsageIndex = 8030, kGFF4MeshVertexDeclaratorMethod = 8031, kGFF4MeshIndexFormat = 8032, kGFF4MeshInstancedStream = 8033, kGFF4MeshChunkInstancesCount = 8034, kGFF4AcNodeName = 9000, kGFF4AcEdgeStartID = 9001, kGFF4AcEdgeEndID = 9002, kGFF4AcCaption = 9003, kGFF4AcNodeSocketList = 9004, kGFF4AcSocketIsOutput = 9005, kGFF4AcNodeImage = 9006, kGFF4AcEdgeList = 9007, kGFF4AcNodeList = 9008, kGFF4AcNodeColor = 9009, kGFF4AcNodeAnimation = 9010, kGFF4AcCurveControlPointList = 9011, kGFF4AcCurveControlPointTime = 9012, kGFF4AcCurveControlPointValue = 9013, kGFF4AcModelName = 9014, kGFF4AcEventList = 9015, kGFF4AcEventTime = 9016, kGFF4AcEventID = 9017, kGFF4AcNodeLooping = 9018, kGFF4AcFlags = 9019, kGFF4AcTransAnimName = 9020, kGFF4AcTransAnimStart = 9021, kGFF4AcTransAnimLength = 9022, kGFF4AcTransTrackList = 9023, kGFF4AcTransitionList = 9024, kGFF4AcTransLength = 9025, kGFF4AcBlendGroupAnimList = 9100, kGFF4AcBlendGroupList = 9101, kGFF4AcBlendGroupName = 9102, kGFF4G2DAColumnName = 10000, kGFF4G2DAColumnHash = 10001, kGFF4G2DAColumnList = 10002, kGFF4G2DARowList = 10003, kGFF4G2DARowData = 10004, kGFF4G2DAColumn1 = 10005, kGFF4G2DAColumn2 = 10006, kGFF4G2DAColumn3 = 10007, kGFF4G2DAColumn4 = 10008, kGFF4G2DAColumn5 = 10009, kGFF4G2DAColumn6 = 10010, kGFF4G2DAColumn7 = 10011, kGFF4G2DAColumn8 = 10012, kGFF4G2DAColumn9 = 10013, kGFF4G2DAColumn10 = 10014, kGFF4G2DAColumn11 = 10015, kGFF4G2DAColumn12 = 10016, kGFF4G2DAColumn13 = 10017, kGFF4G2DAColumn14 = 10018, kGFF4G2DAColumn15 = 10019, kGFF4G2DAColumn16 = 10020, kGFF4G2DAColumn17 = 10021, kGFF4G2DAColumn18 = 10022, kGFF4G2DAColumn19 = 10023, kGFF4G2DAColumn20 = 10024, kGFF4G2DAColumn21 = 10025, kGFF4G2DAColumn22 = 10026, kGFF4G2DAColumn23 = 10027, kGFF4G2DAColumn24 = 10028, kGFF4G2DAColumn25 = 10029, kGFF4G2DAColumn26 = 10030, kGFF4G2DAColumn27 = 10031, kGFF4G2DAColumn28 = 10032, kGFF4G2DAColumn29 = 10033, kGFF4G2DAColumn30 = 10034, kGFF4G2DAColumn31 = 10035, kGFF4G2DAColumn32 = 10036, kGFF4G2DAColumn33 = 10037, kGFF4G2DAColumn34 = 10038, kGFF4G2DAColumn35 = 10039, kGFF4G2DAColumn36 = 10040, kGFF4G2DAColumn37 = 10041, kGFF4G2DAColumn38 = 10042, kGFF4G2DAColumn39 = 10043, kGFF4G2DAColumn40 = 10044, kGFF4G2DAColumn41 = 10045, kGFF4G2DAColumn42 = 10046, kGFF4G2DAColumn43 = 10047, kGFF4G2DAColumn44 = 10048, kGFF4G2DAColumn45 = 10049, kGFF4G2DAColumn46 = 10050, kGFF4G2DAColumn47 = 10051, kGFF4G2DAColumn48 = 10052, kGFF4G2DAColumn49 = 10053, kGFF4G2DAColumn50 = 10054, kGFF4G2DAColumn51 = 10055, kGFF4G2DAColumn52 = 10056, kGFF4G2DAColumn53 = 10057, kGFF4G2DAColumn54 = 10058, kGFF4G2DAColumn55 = 10059, kGFF4G2DAColumn56 = 10060, kGFF4G2DAColumn57 = 10061, kGFF4G2DAColumn58 = 10062, kGFF4G2DAColumn59 = 10063, kGFF4G2DAColumn60 = 10064, kGFF4G2DAColumn61 = 10065, kGFF4G2DAColumn62 = 10066, kGFF4G2DAColumn63 = 10067, kGFF4G2DAColumn64 = 10068, kGFF4G2DAColumn65 = 10069, kGFF4G2DAColumn66 = 10070, kGFF4G2DAColumn67 = 10071, kGFF4G2DAColumn68 = 10072, kGFF4G2DAColumn69 = 10073, kGFF4G2DAColumn70 = 10074, kGFF4G2DAColumn71 = 10075, kGFF4G2DAColumn72 = 10076, kGFF4G2DAColumn73 = 10077, kGFF4G2DAColumn74 = 10078, kGFF4G2DAColumn75 = 10079, kGFF4G2DAColumn76 = 10080, kGFF4G2DAColumn77 = 10081, kGFF4G2DAColumn78 = 10082, kGFF4G2DAColumn79 = 10083, kGFF4G2DAColumn80 = 10084, kGFF4G2DAColumn81 = 10085, kGFF4G2DAColumn82 = 10086, kGFF4G2DAColumn83 = 10087, kGFF4G2DAColumn84 = 10088, kGFF4G2DAColumn85 = 10089, kGFF4G2DAColumn86 = 10090, kGFF4G2DAColumn87 = 10091, kGFF4G2DAColumn88 = 10092, kGFF4G2DAColumn89 = 10093, kGFF4G2DAColumn90 = 10094, kGFF4G2DAColumn91 = 10095, kGFF4G2DAColumn92 = 10096, kGFF4G2DAColumn93 = 10097, kGFF4G2DAColumn94 = 10098, kGFF4G2DAColumn95 = 10099, kGFF4G2DAColumn96 = 10100, kGFF4G2DAColumn97 = 10101, kGFF4G2DAColumn98 = 10102, kGFF4G2DAColumn99 = 10103, kGFF4G2DAColumn100 = 10104, kGFF4G2DAColumn101 = 10105, kGFF4G2DAColumn102 = 10106, kGFF4G2DAColumn103 = 10107, kGFF4G2DAColumn104 = 10108, kGFF4G2DAColumn105 = 10109, kGFF4G2DAColumn106 = 10110, kGFF4G2DAColumn107 = 10111, kGFF4G2DAColumn108 = 10112, kGFF4G2DAColumn109 = 10113, kGFF4G2DAColumn110 = 10114, kGFF4G2DAColumn111 = 10115, kGFF4G2DAColumn112 = 10116, kGFF4G2DAColumn113 = 10117, kGFF4G2DAColumn114 = 10118, kGFF4G2DAColumn115 = 10119, kGFF4G2DAColumn116 = 10120, kGFF4G2DAColumn117 = 10121, kGFF4G2DAColumn118 = 10122, kGFF4G2DAColumn119 = 10123, kGFF4G2DAColumn120 = 10124, kGFF4G2DAColumn121 = 10125, kGFF4G2DAColumn122 = 10126, kGFF4G2DAColumn123 = 10127, kGFF4G2DAColumn124 = 10128, kGFF4G2DAColumn125 = 10129, kGFF4G2DAColumn126 = 10130, kGFF4G2DAColumn127 = 10131, kGFF4G2DAColumn128 = 10132, kGFF4G2DAColumn129 = 10133, kGFF4G2DAColumn130 = 10134, kGFF4G2DAColumn131 = 10135, kGFF4G2DAColumn132 = 10136, kGFF4G2DAColumn133 = 10137, kGFF4G2DAColumn134 = 10138, kGFF4G2DAColumn135 = 10139, kGFF4G2DAColumn136 = 10140, kGFF4G2DAColumn137 = 10141, kGFF4G2DAColumn138 = 10142, kGFF4G2DAColumn139 = 10143, kGFF4G2DAColumn140 = 10144, kGFF4G2DAColumn141 = 10145, kGFF4G2DAColumn142 = 10146, kGFF4G2DAColumn143 = 10147, kGFF4G2DAColumn144 = 10148, kGFF4G2DAColumn145 = 10149, kGFF4G2DAColumn146 = 10150, kGFF4G2DAColumn147 = 10151, kGFF4G2DAColumn148 = 10152, kGFF4G2DAColumn149 = 10153, kGFF4G2DAColumn150 = 10154, kGFF4G2DAColumn151 = 10155, kGFF4G2DAColumn152 = 10156, kGFF4G2DAColumn153 = 10157, kGFF4G2DAColumn154 = 10158, kGFF4G2DAColumn155 = 10159, kGFF4G2DAColumn156 = 10160, kGFF4G2DAColumn157 = 10161, kGFF4G2DAColumn158 = 10162, kGFF4G2DAColumn159 = 10163, kGFF4G2DAColumn160 = 10164, kGFF4G2DAColumn161 = 10165, kGFF4G2DAColumn162 = 10166, kGFF4G2DAColumn163 = 10167, kGFF4G2DAColumn164 = 10168, kGFF4G2DAColumn165 = 10169, kGFF4G2DAColumn166 = 10170, kGFF4G2DAColumn167 = 10171, kGFF4G2DAColumn168 = 10172, kGFF4G2DAColumn169 = 10173, kGFF4G2DAColumn170 = 10174, kGFF4G2DAColumn171 = 10175, kGFF4G2DAColumn172 = 10176, kGFF4G2DAColumn173 = 10177, kGFF4G2DAColumn174 = 10178, kGFF4G2DAColumn175 = 10179, kGFF4G2DAColumn176 = 10180, kGFF4G2DAColumn177 = 10181, kGFF4G2DAColumn178 = 10182, kGFF4G2DAColumn179 = 10183, kGFF4G2DAColumn180 = 10184, kGFF4G2DAColumn181 = 10185, kGFF4G2DAColumn182 = 10186, kGFF4G2DAColumn183 = 10187, kGFF4G2DAColumn184 = 10188, kGFF4G2DAColumn185 = 10189, kGFF4G2DAColumn186 = 10190, kGFF4G2DAColumn187 = 10191, kGFF4G2DAColumn188 = 10192, kGFF4G2DAColumn189 = 10193, kGFF4G2DAColumn190 = 10194, kGFF4G2DAColumn191 = 10195, kGFF4G2DAColumn192 = 10196, kGFF4G2DAColumn193 = 10197, kGFF4G2DAColumn194 = 10198, kGFF4G2DAColumn195 = 10199, kGFF4G2DAColumn196 = 10200, kGFF4G2DAColumn197 = 10201, kGFF4G2DAColumn198 = 10202, kGFF4G2DAColumn199 = 10203, kGFF4G2DAColumn200 = 10204, kGFF4G2DAColumn201 = 10205, kGFF4G2DAColumn202 = 10206, kGFF4G2DAColumn203 = 10207, kGFF4G2DAColumn204 = 10208, kGFF4G2DAColumn205 = 10209, kGFF4G2DAColumn206 = 10210, kGFF4G2DAColumn207 = 10211, kGFF4G2DAColumn208 = 10212, kGFF4G2DAColumn209 = 10213, kGFF4G2DAColumn210 = 10214, kGFF4G2DAColumn211 = 10215, kGFF4G2DAColumn212 = 10216, kGFF4G2DAColumn213 = 10217, kGFF4G2DAColumn214 = 10218, kGFF4G2DAColumn215 = 10219, kGFF4G2DAColumn216 = 10220, kGFF4G2DAColumn217 = 10221, kGFF4G2DAColumn218 = 10222, kGFF4G2DAColumn219 = 10223, kGFF4G2DAColumn220 = 10224, kGFF4G2DAColumn221 = 10225, kGFF4G2DAColumn222 = 10226, kGFF4G2DAColumn223 = 10227, kGFF4G2DAColumn224 = 10228, kGFF4G2DAColumn225 = 10229, kGFF4G2DAColumn226 = 10230, kGFF4G2DAColumn227 = 10231, kGFF4G2DAColumn228 = 10232, kGFF4G2DAColumn229 = 10233, kGFF4G2DAColumn230 = 10234, kGFF4G2DAColumn231 = 10235, kGFF4G2DAColumn232 = 10236, kGFF4G2DAColumn233 = 10237, kGFF4G2DAColumn234 = 10238, kGFF4G2DAColumn235 = 10239, kGFF4G2DAColumn236 = 10240, kGFF4G2DAColumn237 = 10241, kGFF4G2DAColumn238 = 10242, kGFF4G2DAColumn239 = 10243, kGFF4G2DAColumn240 = 10244, kGFF4G2DAColumn241 = 10245, kGFF4G2DAColumn242 = 10246, kGFF4G2DAColumn243 = 10247, kGFF4G2DAColumn244 = 10248, kGFF4G2DAColumn245 = 10249, kGFF4G2DAColumn246 = 10250, kGFF4G2DAColumn247 = 10251, kGFF4G2DAColumn248 = 10252, kGFF4G2DAColumn249 = 10253, kGFF4G2DAColumn250 = 10254, kGFF4G2DAColumn251 = 10255, kGFF4G2DAColumn252 = 10256, kGFF4G2DAColumn253 = 10257, kGFF4G2DAColumn254 = 10258, kGFF4G2DAColumn255 = 10259, kGFF4G2DAColumn256 = 10260, kGFF4G2DAColumn257 = 10261, kGFF4G2DAColumn258 = 10262, kGFF4G2DAColumn259 = 10263, kGFF4G2DAColumn260 = 10264, kGFF4G2DAColumn261 = 10265, kGFF4G2DAColumn262 = 10266, kGFF4G2DAColumn263 = 10267, kGFF4G2DAColumn264 = 10268, kGFF4G2DAColumn265 = 10269, kGFF4G2DAColumn266 = 10270, kGFF4G2DAColumn267 = 10271, kGFF4G2DAColumn268 = 10272, kGFF4G2DAColumn269 = 10273, kGFF4G2DAColumn270 = 10274, kGFF4G2DAColumn271 = 10275, kGFF4G2DAColumn272 = 10276, kGFF4G2DAColumn273 = 10277, kGFF4G2DAColumn274 = 10278, kGFF4G2DAColumn275 = 10279, kGFF4G2DAColumn276 = 10280, kGFF4G2DAColumn277 = 10281, kGFF4G2DAColumn278 = 10282, kGFF4G2DAColumn279 = 10283, kGFF4G2DAColumn280 = 10284, kGFF4G2DAColumn281 = 10285, kGFF4G2DAColumn282 = 10286, kGFF4G2DAColumn283 = 10287, kGFF4G2DAColumn284 = 10288, kGFF4G2DAColumn285 = 10289, kGFF4G2DAColumn286 = 10290, kGFF4G2DAColumn287 = 10291, kGFF4G2DAColumn288 = 10292, kGFF4G2DAColumn289 = 10293, kGFF4G2DAColumn290 = 10294, kGFF4G2DAColumn291 = 10295, kGFF4G2DAColumn292 = 10296, kGFF4G2DAColumn293 = 10297, kGFF4G2DAColumn294 = 10298, kGFF4G2DAColumn295 = 10299, kGFF4G2DAColumn296 = 10300, kGFF4G2DAColumn297 = 10301, kGFF4G2DAColumn298 = 10302, kGFF4G2DAColumn299 = 10303, kGFF4G2DAColumnType = 10999, kGFF4StagePlaceList = 11000, kGFF4StageCameraList = 11001, kGFF4StagePlacesInShot = 11002, kGFF4StageCameraFOV = 11003, kGFF4StagePlaceDefaultCamera = 11004, kGFF4StageCameraDeprecated = 11005, kGFF4StageCameraLookingFrom = 11006, kGFF4StageCameraLookingAtPrimary = 11007, kGFF4StageCameraLookingAtSecondary = 11008, kGFF4StageCameraLookingAtType = 11009, kGFF4ConversationStartingList = 12000, kGFF4ConversationStartingIndex = 12001, kGFF4ConversationLineList = 12002, kGFF4ConversationEnd = 12003, kGFF4ConversationVOBank = 12004, kGFF4ConversationStageName = 12100, kGFF4ConversationStageMap = 12101, kGFF4ConversationKeyTag = 12102, kGFF4ConversationValueTag = 12103, kGFF4ConversationStageAtCurrentLocation = 12104, kGFF4ConversationLineText = 12201, kGFF4ConversationLineSpeaker = 12202, kGFF4ConversationLineListener = 12203, kGFF4ConversationLineGameLanguage = 12204, kGFF4ConversationLineIcon = 12205, kGFF4ConversationLineVisibility = 12206, kGFF4ConversationLineAmbient = 12207, kGFF4ConversationLineCond = 12208, kGFF4ConversationLineAction = 12209, kGFF4ConversationLineCutResRef = 12210, kGFF4ConversationLineCut = 12211, kGFF4ConversationLineCutMap = 12212, kGFF4ConversationLineAnimation = 12213, kGFF4ConversationLineSkip = 12214, kGFF4ConversationLineFastPath = 12215, kGFF4ConversationLineNoVOIngame = 12216, kGFF4ConversationLineRevertAnim = 12217, kGFF4ConversationLineSlideShowTexture = 12218, kGFF4ConversationPlotGuid = 12300, kGFF4ConversationPlotFlag = 12301, kGFF4ConversationPlotTest = 12302, kGFF4ConversationScript = 12303, kGFF4ConversationScriptParameter = 12304, kGFF4ConversationLineChildrenList = 12400, kGFF4ConversationLineActive = 12500, kGFF4PlotFlags = 13000, kGFF4PlotFlagID = 13001, kGFF4PlotFlagName = 13002, kGFF4PlotFlagReward = 13003, kGFF4PlotFlagJournal = 13004, kGFF4PlotFlagEndsPlot = 13005, kGFF4PlotFlagMultiReward = 13006, kGFF4PlotGuid = 13007, kGFF4PlotName = 13008, kGFF4PlotScript = 13009, kGFF4PlotPriority = 13010, kGFF4PlotFlags1 = 13011, kGFF4PlotFlags2 = 13012, kGFF4PlotFlags3 = 13013, kGFF4PlotFlags4 = 13014, kGFF4PlotJournalImage = 13015, kGFF4PlotPlots = 13016, kGFF4PlotParentPlot = 13017, kGFF4PlotFlagAreaLocationTag = 13018, kGFF4PlotAssistList = 13019, kGFF4PlotAssistTag = 13020, kGFF4PlotAssistAdvancesPlot = 13021, kGFF4PlotEntryType = 13022, kGFF4PlotAllowPausing = 13023, kGFF4PlotFlagOfferID = 13024, kGFF4PlotParentPlotGuid = 13025, kGFF4TintMaskDiffuseR = 14000, kGFF4TintMaskDiffuseG = 14001, kGFF4TintMaskDiffuseB = 14002, kGFF4TintMaskSpecularR = 14003, kGFF4TintMaskSpecularG = 14004, kGFF4TintMaskSpecularB = 14005, kGFF4TintMaskDiffuseA = 14006, kGFF4TintMaskSpecularA = 14007, kGFF4TintMaskDiffuseOpacity = 14008, kGFF4TintMaskSpecularOpacity = 14009, kGFF4MatFileObjectVersion = 15000, kGFF4MatChildList = 15001, kGFF4MatRoot = 15010, kGFF4MatRootName = 15011, kGFF4MatModel = 15012, kGFF4MatModelName = 15013, kGFF4MatPart = 15014, kGFF4MatPartName = 15015, kGFF4MatPartMMHParent = 15016, kGFF4MatMatLib = 15017, kGFF4MatMatLibName = 15018, kGFF4MatMatObj = 15019, kGFF4MatMatObjName = 15020, kGFF4MatLight = 15021, kGFF4MatLightName = 15022, kGFF4MatLightRig = 15023, kGFF4MatLightRigName = 15024, kGFF4MatLightProbe = 15025, kGFF4MatLightProbeName = 15026, kGFF4MatGroup = 15027, kGFF4MatGroupName = 15028, kGFF4MatPalettelIb = 15029, kGFF4MatPalettelIbName = 15030, kGFF4MatPaletteObj = 15031, kGFF4MatPaletteObjName = 15032, kGFF4MatHeraldryLib = 15033, kGFF4MatHeraldryLibName = 15034, kGFF4MatHeraldryObj = 15035, kGFF4MatHeraldryObjName = 15036, kGFF4MatDuplicate = 15037, kGFF4MatDuplicateName = 15038, kGFF4MatLayoutName = 15039, kGFF4MatTintLib = 15040, kGFF4MatTintLibName = 15041, kGFF4MatTintObj = 15042, kGFF4MatTintObjName = 15043, kGFF4MatMaterialType = 15050, kGFF4MatBasicParams = 15051, kGFF4MatShinyTrans = 15052, kGFF4MatTwoSide = 15053, kGFF4MatHair = 15054, kGFF4MatDyncLight = 15055, kGFF4MatBlendMode = 15056, kGFF4MatName = 15057, kGFF4MatMaterialTypeString = 15058, kGFF4MatMaterialSemantic = 15059, kGFF4MatMaterialSoundType = 15060, kGFF4MatDiffuseMapType = 15070, kGFF4MatDiffuseMapColor = 15071, kGFF4MatDiffuseMapScale = 15072, kGFF4MatDiffuseMap = 15073, kGFF4MatDiffuseFileName = 15074, kGFF4MatDiffOpacDimensionX = 15075, kGFF4MatDiffOpacDimensionY = 15076, kGFF4MatDiffOpacCompression = 15077, kGFF4MatDiffOpacCompressionXbox360 = 15078, kGFF4MatSecondaryDiffuseMapEnable = 15080, kGFF4MatSecondaryDiffuseMap = 15081, kGFF4MatSecondaryDiffuseFileName = 15082, kGFF4MatSecondaryDiffuseCompression = 15085, kGFF4MatSecondaryDiffuseCompressionXbox360 = 15086, kGFF4MatOpacitymapenable = 15100, kGFF4MatOpacitymaptype = 15101, kGFF4MatOpacitymapcolor = 15102, kGFF4MatOpacitymapscale = 15103, kGFF4MatOpacitymap = 15104, kGFF4MatSpecularMapEnable = 15130, kGFF4MatSpecularMapType = 15131, kGFF4MatSpecularMapColor = 15132, kGFF4MatSpecularMapScale = 15133, kGFF4MatSpecularMap = 15134, kGFF4MatSpecularGlossType = 15135, kGFF4MatSpecularGlossColor = 15136, kGFF4MatSpecularGlossScale = 15137, kGFF4MatSpecularGloss = 15138, kGFF4MatSpecularFileName = 15139, kGFF4MatSpecularDimensionX = 15140, kGFF4MatSpecularDimensionY = 15141, kGFF4MatSpecularCompression = 15142, kGFF4MatSpecularCompressionXbox360 = 15143, kGFF4MatSpecularReflectionMultiplier = 15144, kGFF4MatNormalMapEnable = 15160, kGFF4MatNormalMap = 15161, kGFF4MatNormalFileName = 15162, kGFF4MatNormalCompression = 15163, kGFF4MatNormalCompressionXbox360 = 15164, kGFF4MatTintMapEnable = 15190, kGFF4MatTintMap = 15191, kGFF4MatTintREnable = 15192, kGFF4MatTintGEnable = 15193, kGFF4MatTintBEnable = 15194, kGFF4MatTintFileNamePostfix = 15195, kGFF4MatTintCompression = 15196, kGFF4MatTintCompressionXbox360 = 15197, kGFF4MatTintAEnable = 15198, kGFF4MatTintRSpecularIntensity = 15199, kGFF4MatTintGSpecularIntensity = 15200, kGFF4MatTintBSpecularIntensity = 15201, kGFF4MatTintASpecularIntensity = 15202, kGFF4MatTintRDiffuseIntensity = 15203, kGFF4MatTintGDiffuseIntensity = 15204, kGFF4MatTintBDiffuseIntensity = 15205, kGFF4MatTintADiffuseIntensity = 15206, kGFF4MatTintRSpecularOpacity = 15207, kGFF4MatTintGSpecularOpacity = 15208, kGFF4MatTintBSpecularOpacity = 15209, kGFF4MatTintASpecularOpacity = 15210, kGFF4MatTintRDiffuseOpacity = 15211, kGFF4MatTintGDiffuseOpacity = 15212, kGFF4MatTintBDiffuseOpacity = 15213, kGFF4MatTintADiffuseOpacity = 15214, kGFF4MatTintType = 15215, kGFF4MatTintMaskTintChannel1 = 15216, kGFF4MatTintMaskTintChannel2 = 15217, kGFF4MatTintMaskTintChannel3 = 15218, kGFF4MatTintMaskTintChannel4 = 15219, kGFF4MatReliefMapEnable = 15220, kGFF4MatReliefMap = 15221, kGFF4MatReliefMapScale = 15222, kGFF4MatReliefMapSamples = 15223, kGFF4MatReliefMapShadowOffset = 15224, kGFF4MatReliefMapInOut = 15225, kGFF4MatReliefCompression = 15226, kGFF4MatReliefCompressionXbox360 = 15227, kGFF4MatTintExportable = 15228, kGFF4MatVFXContactSheetWidth = 15250, kGFF4MatVFXContactSheetHeight = 15251, kGFF4MatVFXContactSheetFrames = 15252, kGFF4MatVFXScrollSpeedU = 15253, kGFF4MatVFXScrollSpeedV = 15254, kGFF4MatVFXDepthBiasAlpha = 15255, kGFF4MatVFXStartAlphaFresnel = 15256, kGFF4MatVFXEndAlphaFresnel = 15257, kGFF4MatVFXInvertAlphaFresnel = 15258, kGFF4MatFresnelMapEnable = 15280, kGFF4MatFresnelMap = 15281, kGFF4MatFresnelFileName = 15282, kGFF4MatFresnelCompression = 15283, kGFF4MatFresnelCompressionXbox360 = 15284, kGFF4MatEmissiveMapEnable = 15310, kGFF4MatEmissiveMap = 15311, kGFF4MatEmissiveFileName = 15312, kGFF4MatEmissiveCompression = 15313, kGFF4MatEmissiveCompressionXbox360 = 15314, kGFF4MatSectionMaskMapEnable = 15340, kGFF4MatSectionMaskMap = 15341, kGFF4MatSectionMaskFileName = 15342, kGFF4MatSectionMaskCompression = 15343, kGFF4MatSectionMaskCompressionXbox360 = 15344, kGFF4MatSecondaryNormalMapEnable = 15360, kGFF4MatSecondaryNormalMap = 15361, kGFF4MatSecondaryNormalFileName = 15362, kGFF4MatSecondaryNormalCompression = 15363, kGFF4MatSecondaryNormalCompressionXbox360 = 15364, kGFF4MatEyeCorneaSpecularMask = 15380, kGFF4MatEyeCorneaSpecularPower = 15381, kGFF4MatEyeScleraSpecularMask = 15382, kGFF4MatEyeScleraSpecularPower = 15383, kGFF4MatEyeCorneaReflectionMultiplier = 15384, kGFF4MatSpecularMaskMapEnable = 15400, kGFF4MatPackedTextureMap = 15401, kGFF4MatPackedTextureFileName = 15402, kGFF4MatPackedTextureCompression = 15403, kGFF4MatPackedTextureCompressionXbox360 = 15404, kGFF4MatSpecularShiftMapEnable = 15420, kGFF4MatTintNoiseMap = 15421, kGFF4MatTintNoiseFileName = 15422, kGFF4MatTintNoiseCompression = 15423, kGFF4MatTintNoiseCompressionXbox360 = 15424, kGFF4MatHairDiffuseTint = 15440, kGFF4MatHairPrimarySpecularPower = 15441, kGFF4MatHairPrimarySpecularMask = 15442, kGFF4MatHairSecondarySpecularPower = 15443, kGFF4MatHairSecondarySpecularTint = 15444, kGFF4MatHairTintNoiseTiling = 15445, kGFF4MatSun = 15460, kGFF4MatSunName = 15461, kGFF4MatSunDirection = 15462, kGFF4MatSunColor = 15463, kGFF4MatSunColormult = 15464, kGFF4MatHeraldryMapEnable = 15480, kGFF4MatHeraldryMap = 15481, kGFF4MatHeraldryFileName = 15482, kGFF4MatHeraldryCompression = 15483, kGFF4MatHeraldryCompressionXbox360 = 15484, kGFF4MatRimLightWidth = 15500, kGFF4MatRimLightMultiplier = 15501, kGFF4MatFalloffWidth = 15502, kGFF4MatFalloffMultiplier = 15503, kGFF4MatAmbientMultiplier = 15510, kGFF4MatSpecularMultiplier = 15511, kGFF4MatLipSpecularBoost = 15512, kGFF4MatRimPower = 15513, kGFF4MatDistortionMapEnable = 15520, kGFF4MatDistortionMap = 15521, kGFF4MatDistortionFileName = 15522, kGFF4MatDistortionCompression = 15523, kGFF4MatDistortionCompressionXbox360 = 15524, kGFF4MatDistortionModifiersMapEnable = 15540, kGFF4MatDistortionModifiersMap = 15541, kGFF4MatDistortionModifiersFileName = 15542, kGFF4MatDistortionModifiersCompression = 15543, kGFF4MatDistortionModifiersCompressionXbox360 = 15544, kGFF4MatDistortionMagnitude = 15560, kGFF4MatDistortionInvert = 15561, kGFF4MatDistortionFadeDistance = 15562, kGFF4MatDistortionFadeMultiplier = 15563, kGFF4MatAlternateDecalMap = 15580, kGFF4MatAlternateDecalFileName = 15581, kGFF4MatAlternateDecalCompression = 15582, kGFF4MatAlternateDecalCompressionXbox360 = 15583, kGFF4MatTattooMaskMap = 15590, kGFF4MatTattooMaskFileName = 15591, kGFF4MatTattooMaskCompression = 15592, kGFF4MatTattooMaskCompressionXbox360 = 15593, kGFF4MatTattooMaskMapEnable = 15594, kGFF4MatTattooMaskTintChannel1 = 15595, kGFF4MatTattooMaskTintChannel2 = 15596, kGFF4MatTattooMaskTintChannel3 = 15597, kGFF4MatTattooMaskTintChannel4 = 15598, kGFF4MatBrowStubbleMap = 15600, kGFF4MatBrowStubbleFileName = 15601, kGFF4MatBrowStubbleCompression = 15602, kGFF4MatBrowStubbleCompressionXbox360 = 15603, kGFF4MatBrowStubbleNormalMap = 15610, kGFF4MatBrowStubbleNormalFileName = 15611, kGFF4MatBrowStubbleNormalCompression = 15612, kGFF4MatBrowStubbleNormalCompressionXbox360 = 15613, kGFF4MatEmotionsMask0Map = 15620, kGFF4MatEmotionsMask0FileName = 15621, kGFF4MatEmotionsMask0Compression = 15622, kGFF4MatEmotionsMask0CompressionXbox360 = 15623, kGFF4MatEmotionsMask1Map = 15630, kGFF4MatEmotionsMask1FileName = 15631, kGFF4MatEmotionsMask1Compression = 15632, kGFF4MatEmotionsMask1CompressionXbox360 = 15633, kGFF4MatEmotionsNormalMap = 15640, kGFF4MatEmotionsNormalFileName = 15641, kGFF4MatEmotionsNormalCompression = 15642, kGFF4MatEmotionsNormalCompressionXbox360 = 15643, kGFF4MatScrollSpeed1 = 15650, kGFF4MatScrollSpeed2 = 15651, kGFF4MatScrollSpeed3 = 15652, kGFF4MatLavaTintColor = 15653, kGFF4MatLavaBrightness = 15654, kGFF4MatLavaContrast = 15655, kGFF4MatLavaNoiseMap = 15656, kGFF4SavegameCampaign = 16000, kGFF4SavegameAreaList = 16001, kGFF4SavegamePlayerchar = 16002, kGFF4SavegamePartyList = 16003, kGFF4SavegameVersion = 16004, kGFF4SavegameGameState = 16005, kGFF4SavegameAddinsList = 16006, kGFF4SavegameCheatUsed = 16007, kGFF4SavegameStorySoFar = 16008, kGFF4SavegameAreaPlaceables = 16010, kGFF4SavegameAreaCreatures = 16011, kGFF4SavegameAreaTriggers = 16012, kGFF4SavegameAreaAOEs = 16013, kGFF4SavegameCampaignResource = 16014, kGFF4SavegameAreaWaypoints = 16015, kGFF4SavegameAreaMap = 16016, kGFF4SavegameAreaStores = 16017, kGFF4SavegameAreaRoomsViewed = 16018, kGFF4SavegameAreaSounds = 16019, kGFF4SavegameAreaMinCreatureImportance = 16020, kGFF4SavegameAreaPlaceableState = 16100, kGFF4SavegameAreaTriggerGeometry = 16101, kGFF4SavegameAreaPlaceableUseable = 16102, kGFF4SavegameAreaTriggerDetectable = 16103, kGFF4SavegameAreaTriggerDisarmable = 16104, kGFF4SavegameAreaTriggerDCDetectCheck = 16105, kGFF4SavegameAreaTriggerDCDisarmCheck = 16106, kGFF4SavegameAreaTriggerLastDisarmed = 16107, kGFF4SavegameAreaTriggerReverbPreset = 16108, kGFF4SavegameAreaTriggerPriority = 16109, kGFF4SavegameAreaTriggerLoadScreen = 16110, kGFF4SavegameAreaTriggerSounds = 16111, kGFF4SavegameAreaTriggerType = 16112, kGFF4SavegameAreaTriggerMusicVolumeEnterState = 16113, kGFF4SavegameAreaTriggerMusicVolumeExitState = 16114, kGFF4SavegameAreaTriggerMusicVolumeEnterStateDelay = 16115, kGFF4SavegameAreaTriggerMusicVolumeExitStateDelay = 16116, kGFF4SavegameStoreMarkDown = 16150, kGFF4SavegameStoreMarkUp = 16151, kGFF4SavegameStoreGold = 16152, kGFF4SavegameStoreMaxBuyPrice = 16153, kGFF4SavegameStoreWillNotBuy = 16154, kGFF4SavegameStoreWillOnlyBuy = 16155, kGFF4SavegameStoreItemList = 16156, kGFF4SavegamePlayercharArea = 16200, kGFF4SavegameObjectActive = 16201, kGFF4SavegameObjectAILevel = 16202, kGFF4SavegamePartyMembers = 16203, kGFF4SavegamePartyPoolMembers = 16204, kGFF4SavegamePartyMemCreature = 16205, kGFF4SavegamePartyMemTemplate = 16206, kGFF4SavegamePartyCreatures = 16207, kGFF4SavegamePlayerCharChar = 16208, kGFF4SavegameCreatureStats = 16209, kGFF4SavegameBackpack = 16210, kGFF4SavegamePlotItems = 16211, kGFF4SavegameMoney = 16212, kGFF4SavegameQuickItems = 16213, kGFF4SavegameEquipment = 16214, kGFF4SavegameEquipmentSet = 16215, kGFF4SavegameEquipmentSetSlot = 16216, kGFF4SavegameEquipmentSetObject = 16217, kGFF4SavegameEquipmentActiveSet = 16218, kGFF4SavegameEquipmentItems = 16219, kGFF4SavegameObjectImmortal = 16220, kGFF4SavegameObjectEventScript = 16221, kGFF4SavegameObjectTag = 16222, kGFF4SavegameItems = 16223, kGFF4SavegameItemDroppable = 16224, kGFF4SavegameItemDamaged = 16225, kGFF4SavegameMaxItems = 16226, kGFF4SavegameCraftingRecipeList = 16227, kGFF4SavegameItemIrremovable = 16228, kGFF4SavegameItemIndestructible = 16229, kGFF4SavegameItemMaterialType = 16230, kGFF4SavegameItemStealable = 16231, kGFF4SavegameItemInfinite = 16232, kGFF4SavegameItemCurrentVFXPropertyID = 16233, kGFF4SavegameItemCurrentVFXPropertyPower = 16234, kGFF4SavegameObjectPlot = 16250, kGFF4SavegameObjectHealth = 16251, kGFF4SavegameObjectMaxHealth = 16252, kGFF4SavegameObjectRank = 16253, kGFF4SavegameObjectTreasureGroup = 16254, kGFF4SavegameObjectName = 16255, kGFF4SavegameObjectLoopingAnimation = 16256, kGFF4SavegameObjectLootableCreatureAppearanceType = 16257, kGFF4SavegameObjectPickLock = 16258, kGFF4SavegameObjectTrapDetected = 16259, kGFF4SavegameObjectDCDetectCheck = 16260, kGFF4SavegameObjectDCDisarmCheck = 16261, kGFF4SavegameObjectInteractionRadius = 16262, kGFF4SavegameObjectImportance = 16263, kGFF4SavegameSelectedCharacter = 16270, kGFF4SavegameFollowerLastEnabledArea = 16271, kGFF4SavegameFollowerLastEnabledPosition = 16272, kGFF4SavegameFollowerLastEnabledOrientation = 16273, kGFF4SavegamePartyPickerGUIStatus = 16274, kGFF4SavegamePartyApprovalList = 16275, kGFF4SavegamePartyApprovalID = 16276, kGFF4SavegamePartyApprovalLevel = 16277, kGFF4SavegamePartyLeader = 16278, kGFF4SavegameNonPartyMembers = 16279, kGFF4SavegamePartyMemberSubstate = 16280, kGFF4SavegamePartyMemberLocked = 16281, kGFF4SavegamePartyMemberFollow = 16282, kGFF4SavegamePartyItemStorageItem = 16284, kGFF4SavegamePartyItemStorageOwner = 16285, kGFF4SavegamePartyItemStorageSlot = 16286, kGFF4SavegamePartyItemStorageWeaponset = 16287, kGFF4SavegamePartyItemStorageList = 16288, kGFF4SavegamePartyNewItemID = 16289, kGFF4SavegamePartyNewItemList = 16290, kGFF4SavegamePartyAutoLevelDefault = 16291, kGFF4SavegamePartyQuickbarLocked = 16292, kGFF4SavegamePartyHoldPositions = 16293, kGFF4SavegamePartyRunInDriveMode = 16294, kGFF4SavegamePlayerMapZoom = 16295, kGFF4SavegamePlayerMapLegend = 16296, kGFF4SavegamePartyApprovalDesc = 16297, kGFF4SavegamePlayerTimePlayed = 16298, kGFF4SavegamePartyBackpackSort = 16299, kGFF4SavegameStatPropertyBase = 16300, kGFF4SavegameStatPropertyModifier = 16301, kGFF4SavegameStatPropertyCurrent = 16302, kGFF4SavegameStatPropertyComRegen = 16303, kGFF4SavegameStatPropertyRegen = 16304, kGFF4SavegameSpellList = 16305, kGFF4SavegameTalentList = 16306, kGFF4SavegameSkillList = 16307, kGFF4SavegameQuickslots = 16308, kGFF4SavegameAbilityList = 16309, kGFF4SavegameQbarExpansionValue = 16310, kGFF4SavegameQuickslotAbility = 16311, kGFF4SavegameQuickslotItemTag = 16312, kGFF4SavegameQuickslots1 = 16313, kGFF4SavegameQuickslots2 = 16314, kGFF4SavegameQuickslots3 = 16315, kGFF4SavegameQuickslots4 = 16316, kGFF4SavegameCurentQbar = 16317, kGFF4SavegameLockQbar = 16318, kGFF4SavegameQuickslotTemplate = 16319, kGFF4SavegameAppearance = 16320, kGFF4SavegameAppearanceType = 16321, kGFF4SavegameAppearanceGender = 16322, kGFF4SavegameAppearanceGore = 16324, kGFF4SavegameAppearanceDecapitated = 16325, kGFF4SavegameAppearanceItemHeraldryVariation = 16326, kGFF4SavegameAppearanceOriginalType = 16327, kGFF4SavegameAppearanceMorphName = 16328, kGFF4SavegameAutoLevelUp = 16329, kGFF4SavegamePromptAutoLevelUp = 16330, kGFF4SavegameQuickslotNumber = 16331, kGFF4SavegamePlayerPortraitPitch = 16332, kGFF4SavegamePlayerPortraitYaw = 16333, kGFF4SavegamePlayerPortraitTint = 16334, kGFF4SavegamePlayerPortraitExpression = 16335, kGFF4SavegamePlayerPortraitDistance = 16336, kGFF4SavegamePlayerPortraitPositionH = 16337, kGFF4SavegamePlayerPortraitPositionV = 16338, kGFF4SavegameStatList = 16350, kGFF4SavegameHeroicStatList = 16351, kGFF4SavegameHeroicPartyStatList = 16352, kGFF4SavegameStatPropertyIndex = 16353, kGFF4SavegameStatPropertyMin = 16354, kGFF4SavegameStatPropertyMax = 16355, kGFF4SavegamePlotManager = 16400, kGFF4SavegamePlotList = 16401, kGFF4SavegamePlotGuid = 16402, kGFF4SavegamePlotFlags1 = 16403, kGFF4SavegamePlotFlags2 = 16404, kGFF4SavegamePlotFlags3 = 16405, kGFF4SavegamePlotFlags4 = 16406, kGFF4StructSavegameAddinUID = 16420, kGFF4StructSavegameAddinENUS = 16421, kGFF4StructSavegameAddinFRFR = 16422, kGFF4StructSavegameAddinITIT = 16423, kGFF4StructSavegameAddinDEDE = 16424, kGFF4StructSavegameAddinESES = 16425, kGFF4StructSavegameAddinPLPL = 16426, kGFF4StructSavegameAddinRURU = 16427, kGFF4StructSavegameAddinPseudo = 16428, kGFF4StructSavegameAddinCSCZ = 16429, kGFF4StructSavegameAddinHUHU = 16430, kGFF4SavegameGroupList = 16450, kGFF4SavegameGroupID = 16451, kGFF4SavegameGroupHostiles = 16452, kGFF4SavegameTeamID = 16453, kGFF4SavegameCreatureStealth = 16454, kGFF4SavegameIsPlotGiver = 16455, kGFF4SavegameCanLevelUp = 16456, kGFF4SavegameCreatureTrackable = 16457, kGFF4SavegameCreatureControllable = 16458, kGFF4SavegameCreatureInteractive = 16459, kGFF4SavegameCreatureRace = 16460, kGFF4SavegameCreaturePackage = 16461, kGFF4SavegameCreaturePackageAI = 16462, kGFF4SavegameCreatureCanChangeEquipment = 16463, kGFF4SavegameCreatureClassRankList = 16464, kGFF4SavegameCreatureClassID = 16465, kGFF4SavegameCreatureClassRank = 16466, kGFF4SavegameCreatureIsGhost = 16467, kGFF4SavegameCreatureModalAbilityList = 16468, kGFF4SavegameCreatureShowAsAllyOnMap = 16469, kGFF4SavegameCreatureIsStatue = 16470, kGFF4SavegameCreatureMinimizedSkillHeaderList = 16471, kGFF4SavegameCreatureMinimizedTalentHeaderList = 16472, kGFF4SavegameCreatureAbilityHeaderID = 16473, kGFF4SavegameCreatureItemsScaled = 16474, kGFF4SavegameCreatureHeartbeatInterval = 16475, kGFF4SavegameCreatureRoamRadius = 16476, kGFF4SavegameCreatureRoamCenter = 16477, kGFF4SavegameCreaturePoolName = 16478, kGFF4SavegameCreaturePoolAvailable = 16479, kGFF4SavegameCreatureNoPermDeath = 16480, kGFF4SavegameCreatureTimeSinceDeath = 16481, kGFF4SavegameCreatureTimeBeforeDecay = 16499, kGFF4SavegameWorldDatabase = 16500, kGFF4SavegameWorldDBIDgroup = 16501, kGFF4SavegameWorldDBLastID = 16502, kGFF4SavegamePartySeenLines = 16503, kGFF4SavegameJournal = 16504, kGFF4SavegameJournalActiveList = 16505, kGFF4SavegameJournalCompleteList = 16506, kGFF4SavegameJournalTitle = 16507, kGFF4SavegameJournalText = 16508, kGFF4SavegameJournalParentPlot = 16509, kGFF4SavegameJournalResRef = 16510, kGFF4SavegameJournalStoryText = 16511, kGFF4SavegameJournalAreaTag = 16512, kGFF4SavegameJournalPlotDestinationList = 16513, kGFF4SavegameJournalPlotDestinationTag = 16514, kGFF4SavegameJournalPlotDestinationGuidList = 16515, kGFF4SavegameJournalConversationList = 16516, kGFF4SavegameJournalConversationLineList = 16517, kGFF4SavegameJournalConversationLineSpeaker = 16518, kGFF4SavegameJournalConversationLineText = 16519, kGFF4SavegameJournalConversationLineReply = 16520, kGFF4SavegameJournalUnreadCodexList = 16521, kGFF4SavegameJournalOrphanList = 16522, kGFF4SavegameJournalQuestCompleted = 16523, kGFF4SavegameJournalQuestGroup = 16524, kGFF4SavegameJournalGroupList = 16525, kGFF4SavegameJournalGroupResRef = 16526, kGFF4SavegameJournalGroupOpenInCurrent = 16527, kGFF4SavegameJournalGroupOpenInCompleted = 16528, kGFF4SavegameJournalGroupPriority = 16529, kGFF4SavegameAmbientDialogList = 16530, kGFF4SavegameAmbientDialogOwner = 16531, kGFF4SavegameAmbientDialogSpeaker = 16532, kGFF4SavegameAmbientDialogResRef = 16533, kGFF4SavegameAmbientDialogLine = 16534, kGFF4SavegameJournalQuestUpdated = 16540, kGFF4SavegameJournalOfferID = 16541, kGFF4SavegameBodybagID = 16600, kGFF4SavegameIsBodybag = 16601, kGFF4SavegameLootableObjectID = 16602, kGFF4SavegameAOEID = 16603, kGFF4SavegameAOEShape = 16604, kGFF4SavegameAOERadius = 16605, kGFF4SavegameAOEWidth = 16606, kGFF4SavegameAOELength = 16607, kGFF4SavegameAOECreator = 16608, kGFF4SavegameAOEDuration = 16609, kGFF4SavegameAOEDurationType = 16610, kGFF4SavegameAOELinked = 16611, kGFF4SavegameCreatureRank = 16612, kGFF4SavegameEffectID = 16613, kGFF4SavegameEffectType = 16614, kGFF4SavegameEffectDurationType = 16615, kGFF4SavegameEffectDuration = 16616, kGFF4SavegameEffectSubType = 16617, kGFF4SavegameEffectTimeIndex = 16618, kGFF4SavegameEffectAnimation = 16619, kGFF4SavegameEffectPriority = 16620, kGFF4SavegameEffectCreator = 16621, kGFF4SavegameEffectAbilityID = 16622, kGFF4SavegameEffectList = 16623, kGFF4SavegameEffectEngineData = 16624, kGFF4SavegameEffectResource2 = 16625, kGFF4SavegameEffectStartingID = 16626, kGFF4SavegameEffectFlags = 16627, kGFF4SavegameAIMaster = 16636, kGFF4SavegameEventQueue = 16630, kGFF4SavegameEventDay = 16631, kGFF4SavegameEventTime = 16632, kGFF4SavegameEventCallerID = 16633, kGFF4SavegameEventTargetID = 16634, kGFF4SavegameEventID = 16635, kGFF4SavegameDataarray = 16640, kGFF4SavegameDataarrayInt = 16641, kGFF4SavegameDataarrayFloat = 16642, kGFF4SavegameDataarrayBool = 16643, kGFF4SavegameDataarrayOID = 16644, kGFF4SavegameDataarrayString = 16645, kGFF4SavegameDataarrayVector = 16646, kGFF4SavegameDataarrayQuaternion = 16647, kGFF4SavegameEventScript = 16650, kGFF4SavegameEventSimpleValue = 16651, kGFF4SavegameScriptEventType = 16670, kGFF4SavegameScriptEventCreator = 16671, kGFF4SavegameScriptEventTarget = 16672, kGFF4SavegameScriptEventData = 16673, kGFF4SavegameScriptEventScriptName = 16674, kGFF4SavegameScriptEventResourceList = 16675, kGFF4SavegameWorldTimer = 16700, kGFF4SavegameWorldTimerDay = 16701, kGFF4SavegameWorldTimerTime = 16702, kGFF4SavegameWaypointMapNote = 16710, kGFF4SavegameWaypointMapNoteEnabled = 16711, kGFF4SavegameWaypointMapNoteText = 16712, kGFF4SavegameWaypointMapNoteType = 16713, kGFF4SavegameWaypointMapNoteLocText = 16714, kGFF4SavegameCurrentCommand = 16720, kGFF4SavegameCommandList = 16721, kGFF4SavegameCommandCommandid = 16722, kGFF4SavegameCommandID = 16723, kGFF4SavegameCommandStatic = 16724, kGFF4SavegameCommandData = 16725, kGFF4SavegameCommandPlayerIssued = 16726, kGFF4SavegameSubactionList = 16730, kGFF4SavegameSubactionID = 16731, kGFF4SavegameSubactionCoreSubaction = 16732, kGFF4SavegameSubactionCoreInterruptable = 16733, kGFF4SavegameSubactionTimeIndex = 16734, kGFF4SavegameSubactionLastTimeIndex = 16735, kGFF4SavegameSubactionLength = 16736, kGFF4SaveNameSubactionStartTime = 16737, kGFF4SavegameSubactionData = 16738, kGFF4SavegameCurrentActionQueue = 16740, kGFF4SavegameAOEAbilityID = 16750, kGFF4SavegameAOEFlags = 16751, kGFF4SavegameAOEStationary = 16752, kGFF4SavegameBuildNumber = 16770, kGFF4SavegameSaveVersionInternal = 16771, kGFF4SavegameWorldmap = 16780, kGFF4SavegameWorldmapPrimaryMap = 16781, kGFF4SavegameWorldmapSecondaryMap = 16782, kGFF4SavegameWorldmapMapList = 16783, kGFF4SavegameWorldmapMapTag = 16784, kGFF4SavegameWorldmapMapPlayerLoc = 16785, kGFF4SavegameWorldmapMapPinList = 16786, kGFF4SavegameWorldmapMapPinTag = 16787, kGFF4SavegameWorldmapMapPinState = 16788, kGFF4SavegameWorldmapMapPinRecentlyActivated = 16789, kGFF4SavegameWorldmapGUIStatus = 16790, kGFF4SavegameWorldmapLastPinClicked = 16791, kGFF4SavegameWorldmapMapPinActivatedPreviously = 16792, kGFF4SavegameWorldmapMapPinLastState = 16793, kGFF4SavegameWorldmapTravelPointPosX = 16794, kGFF4SavegameWorldmapTravelPointPosY = 16795, kGFF4SavegameWorldmapMapTravelPathBefore = 16796, kGFF4SavegameWorldmapMapTravelPathAfter = 16797, kGFF4SavegameWorldmapMapPinName = 16798, kGFF4SavegameMetaAreaName = 16800, kGFF4SavegameMetaTimePlayed = 16801, kGFF4SavegameMetaLevel = 16802, kGFF4SavegameMetaClass = 16803, kGFF4SavegameMetaGender = 16804, kGFF4SavegameMetaRace = 16805, kGFF4SavegameMetaBackground = 16806, kGFF4SavegameMetaName = 16807, kGFF4SavegameMetaSaveName = 16808, kGFF4SavegameTacticEntryTargetObjectID = 16818, kGFF4SavegameTacticEntryConditionObjectID = 16819, kGFF4SavegamePartyTacticsItemAbilities = 16820, kGFF4SavegameTacticsHasTable = 16821, kGFF4SavegameTacticsTable = 16822, kGFF4SavegameTacticsEnabled = 16823, kGFF4SavegameTacticsList = 16824, kGFF4SavegameTacticEntryEnabled = 16825, kGFF4SavegameTacticEntryTarget = 16826, kGFF4SavegameTacticEntryCondition = 16827, kGFF4SavegameTacticEntryCommand = 16828, kGFF4SavegameTacticEntryCommandParam = 16829, kGFF4SavegameTacticEntryTargetTag = 16830, kGFF4SavegameTacticEntryConditionTag = 16831, kGFF4SavegameTacticsDirty = 16832, kGFF4SavegameTacticsPresetType = 16833, kGFF4SavegameTacticsPresetIndex = 16834, kGFF4SavegameTacticsPresetList = 16835, kGFF4SavegameTacticsCustomList = 16836, kGFF4SavegameTacticEntryCommandItemTag = 16837, kGFF4SavegameTacticEntryCommandItemResRef = 16838, kGFF4SavegamePlotActions = 16840, kGFF4SavegamePlotActionsEnabled = 16841, kGFF4SavegamePlotActionsCurrentSet = 16842, kGFF4SavegamePlotActionsList = 16843, kGFF4SavegamePlotActionID = 16844, kGFF4SavegamePlotActionState = 16845, kGFF4SavegamePlotActionCount = 16846, kGFF4SavegamePlotActionUpdated = 16847, kGFF4SavegameSoundTag = 16900, kGFF4SavegameSoundActive = 16901, kGFF4SavegameSoundName = 16902, kGFF4SavegameSoundXPosition = 16903, kGFF4SavegameSoundYPosition = 16904, kGFF4SavegameSoundZPosition = 16905, kGFF4SavegameSoundXOrientation = 16906, kGFF4SavegameSoundYOrientation = 16907, kGFF4SavegameSoundZOrientation = 16908, kGFF4SavegameSoundWOrientation = 16909, kGFF4SavegameSoundVolume = 16910, kGFF4SavegameSoundPitch = 16911, kGFF4SavegameSoundFadeIn = 16912, kGFF4SavegameSoundFadeOut = 16913, kGFF4SavegameSoundMaxDistanceMult = 16914, kGFF4SavegameSoundConeInside = 16915, kGFF4SavegameSoundConeOutside = 16916, kGFF4SavegameSoundConeVolume = 16917, kGFF4SavegameSoundPriority = 16918, kGFF4SavegameSoundOccludable = 16919, kGFF4SavegamePlayerMorph = 16950, kGFF4SavegamePlayerSoundSet = 16951, kGFF4SavegameDefaultSoundSet = 16952, kGFF4SavegameAddinName = 16960, kGFF4SavegameStorySoFarEventList = 16970, kGFF4SavegameStorySoFarEventID = 16971, kGFF4SavegameStorySoFarGameTime = 16972, kGFF4SavegameStorySoFarUTC = 16973, kGFF4SavegameStorySoFarScreenshot = 16974, kGFF4SavegameStorySoFarLevelUpList = 16975, kGFF4SavegameStorySoFarArea = 16976, kGFF4SavegameStorySoFarLevel = 16977, kGFF4SavegameStorySoFarMoney = 16978, kGFF4SavegameStorySoFarCurrentHealth = 16979, kGFF4SavegameStorySoFarTotalHealth = 16980, kGFF4SavegameStorySoFarCurrentStamina = 16981, kGFF4SavegameStorySoFarTotalStamina = 16982, kGFF4SavegameStorySoFarCurrentXP = 16983, kGFF4SavegameStorySoFarSpellList = 16984, kGFF4SavegameStorySoFarTalentList = 16985, kGFF4SavegameStorySoFarSkillList = 16986, kGFF4SavegameStorySoFarAttributeList = 16987, kGFF4SavegameStorySoFarAttributeBase = 16988, kGFF4SavegameStorySoFarAttributeModifier = 16989, kGFF4SavegameStorySoFarEquipmentList = 16990, kGFF4SavegameStorySoFarEquipmentSlotID = 16991, kGFF4SavegameStorySoFarEquipmentResRef = 16992, kGFF4SavegameStorySoFarEquipmentStackSize = 16993, kGFF4SavegameStorySoFarItemProperty = 16994, kGFF4SavegameStorySoFarItemPower = 16995, kGFF4SavegameStorySoFarItemData = 16996, kGFF4ScriptVarTable = 17000, kGFF4ScriptVarTableName = 17001, kGFF4ScriptVarTableType = 17002, kGFF4ScriptVarTableValue = 17003, kGFF4CampaignCIFEntryAreaList = 17100, kGFF4CampaignCIFEntryArea = 17101, kGFF4CampaignCIFEntryPosition = 17102, kGFF4CampaignCIFEntryOrientation = 17103, kGFF4CampaignCIFEntryScript = 17104, kGFF4CampaignCIFEntryClientScript = 17105, kGFF4CampaignCIFDisplayNameENUS = 17106, kGFF4CampaignCIFDisplayNameFRFR = 17107, kGFF4CampaignCIFDisplayNameDEDE = 17108, kGFF4CampaignCIFDisplayNamePLPL = 17109, kGFF4CampaignCIFDisplayNameRURU = 17110, kGFF4CampaignCIFDisplayNameITIT = 17111, kGFF4CampaignCIFDisplayNameESES = 17112, kGFF4CampaignCIFDisplayNameHUHU = 17113, kGFF4CampaignCIFDisplayNameCSCZ = 17114, kGFF4CampaignCIFDescriptionENUS = 17115, kGFF4CampaignCIFDescriptionFRFR = 17116, kGFF4CampaignCIFDescriptionDEDE = 17117, kGFF4CampaignCIFDescriptionPLPL = 17118, kGFF4CampaignCIFDescriptionRURU = 17119, kGFF4CampaignCIFDescriptionITIT = 17120, kGFF4CampaignCIFDescriptionESES = 17121, kGFF4CampaignCIFDescriptionHUHU = 17122, kGFF4CampaignCIFDescriptionCSCZ = 17123, kGFF4CampaignCIFPackagesList = 17124, kGFF4TalkBucketList = 19000, kGFF4TalkStringList = 19001, kGFF4TalkStringID = 19002, kGFF4TalkString = 19003, kGFF4HuffTalkStringID = 19004, kGFF4HuffTalkStringBitOffset = 19005, kGFF4HuffTalkStringList = 19006, kGFF4HuffTalkStringHuffTree = 19007, kGFF4HuffTalkStringBitStream = 19008, kGFF4PlaceableStatesList = 20000, kGFF4VFXChildList = 21000, kGFF4VFXObjectID = 21001, kGFF4VFXEmitterInitialRotationRange = 21002, kGFF4VFXOrientation = 21003, kGFF4VFXRoot = 21004, kGFF4VFXEmitterMeshParticleRollAxis = 21005, kGFF4VFXType = 21006, kGFF4VFXObjectVisible = 21007, kGFF4VFXEmitterMeshParticleUpAxis = 21008, kGFF4VFXKeyframe = 21009, kGFF4VFXValue = 21010, kGFF4VFXEmitterName = 21011, kGFF4VFXEmitterType = 21012, kGFF4VFXEmitterOrientationBehaviour = 21013, kGFF4VFXEmitterUpdateOnlyWhenVisible = 21014, kGFF4VFXEmitterLinkParticlesTogether = 21015, kGFF4VFXEmitterMaterialLibrary = 21016, kGFF4VFXEmitterMaterialObject = 21017, kGFF4VFXEmitterBirthrate = 21018, kGFF4VFXEmitterBirthrateRange = 21019, kGFF4VFXEmitterBirthrateInParticlesPerMeter = 21020, kGFF4VFXEmitterInitialSpeed = 21021, kGFF4VFXEmitterInitialSpeedRange = 21022, kGFF4VFXEmitterAcceleration = 21023, kGFF4VFXEmitterGravityMultiplier = 21024, kGFF4VFXEmitterLife = 21025, kGFF4VFXEmitterLifeRange = 21026, kGFF4VFXEmitterScaleRange = 21027, kGFF4VFXEmitterSpreadX = 21028, kGFF4VFXEmitterSpreadY = 21029, kGFF4VFXEmitterInitialRotationSpeed = 21030, kGFF4VFXEmitterInitialRotationSpeedRange = 21031, kGFF4VFXEmitterRotationalAcceleration = 21032, kGFF4VFXEmitterRandomInitialRotation = 21033, kGFF4VFXEmitterParticleInheritance = 21034, kGFF4VFXEmitterInheritVelocityInsteadOfPosition = 21035, kGFF4VFXEmitterParticlesAffectedByWind = 21036, kGFF4VFXEmitterEnableParticleCollisions = 21037, kGFF4VFXEmitterPhysicsObjectSpawn = 21038, kGFF4VFXEmitterPhysicsEmitter = 21039, kGFF4VFXEmitterMovementSpreadX = 21040, kGFF4VFXEmitterMovementSpreadY = 21041, kGFF4VFXEmitterMovementSpreadUpdateDelay = 21042, kGFF4VFXEmitterTargetName = 21043, kGFF4VFXEmitterTargetAttraction = 21044, kGFF4VFXEmitterTargetRadius = 21045, kGFF4VFXEmitterSpawnDirectionTracksTarget = 21046, kGFF4VFXEmitterKillParticleWhenTargetHit = 21047, kGFF4VFXEmitterParticlesFollowPath = 21048, kGFF4VFXEmitterFlipbookType = 21049, kGFF4VFXEmitterFlipbookFramesPerSecond = 21050, kGFF4VFXEmitterFlipbookRows = 21051, kGFF4VFXEmitterFlipbookColumns = 21052, kGFF4VFXEmitterFlipbookRandomStartFrame = 21053, kGFF4VFXEmitterAlphaMultiplier = 21054, kGFF4VFXEmitterColorMultiplier = 21055, kGFF4VFXEmitterScaleMultiplier = 21056, kGFF4VFXEmitterInfiniteLife = 21057, kGFF4VFXEmitterChunkyModelName = 21058, kGFF4VFXEmitterInitialRotation = 21059, kGFF4VFXCrustNodeName = 21060, kGFF4VFXCrustNodeRealName = 21061, kGFF4VFXCrustNodeCrustHookID = 21062, kGFF4VFXGeometryFileName = 21063, kGFF4VFXEmitterAgent = 21064, kGFF4VFXUseVariationTint = 21065, kGFF4VFXDummyName = 21070, kGFF4VFXGeometryName = 21080, kGFF4VFXGeometryScale = 21081, kGFF4VFXTargetName = 21090, kGFF4VFXModelName = 21100, kGFF4VFXModelResourcetype = 21101, kGFF4VFXModelAnimationName = 21102, kGFF4VFXCreatureName = 21110, kGFF4VFXCreatureURI = 21111, kGFF4VFXRelativePositionX = 21120, kGFF4VFXRelativePositionY = 21121, kGFF4VFXRelativePositionZ = 21122, kGFF4VFXRelativeOrientationX = 21123, kGFF4VFXRelativeOrientationY = 21124, kGFF4VFXRelativeOrientationZ = 21125, kGFF4VFXImpactLength = 21130, kGFF4VFXDurationLength = 21131, kGFF4VFXCessationLength = 21132, kGFF4VFXCustomLength = 21133, kGFF4VFXCustomName = 21134, kGFF4VFXAgemapColorR = 21140, kGFF4VFXAgemapColorG = 21141, kGFF4VFXAgemapColorB = 21142, kGFF4VFXAgemapColorA = 21143, kGFF4VFXAgemapScaleX = 21144, kGFF4VFXAgemapScaleY = 21145, kGFF4VFXAgemapRotationalSpeedMultiplier = 21146, kGFF4VFXEvent = 21150, kGFF4VFXEventTime = 21151, kGFF4VFXEventType = 21152, kGFF4VFXEventID = 21153, kGFF4VFXEventTargetSystem = 21154, kGFF4VFXEmitterVolumeSpawnType = 21160, kGFF4VFXEmitterVolumeSpawnSelectedPartName = 21161, kGFF4VFXEmitterVolumeSpawnArbitraryVolumeName = 21162, kGFF4VFXEmitterCollisionType = 21163, kGFF4VFXEmitterBounceValue = 21164, kGFF4VFXEmitterVolumeSpawnWithinVolume = 21165, kGFF4VFXEmitterVolumeSpawnInvertNormals = 21166, kGFF4VFXEmitterColorMultiplierR = 21170, kGFF4VFXEmitterColorMultiplierG = 21171, kGFF4VFXEmitterColorMultiplierB = 21172, kGFF4VFXSplatAgemapColorR = 21173, kGFF4VFXSplatAgemapColorG = 21174, kGFF4VFXSplatAgemapColorB = 21175, kGFF4VFXSplatAgemapColorA = 21176, kGFF4VFXSplatAgemapScaleX = 21177, kGFF4VFXSplatAgemapScaleY = 21178, kGFF4VFXFileObjectVersion = 21180, kGFF4VFXEmitterSplatAlphaMultiplier = 21181, kGFF4VFXEmitterSplatColorMultiplierR = 21182, kGFF4VFXEmitterSplatColorMultiplierG = 21183, kGFF4VFXEmitterSplatColorMultiplierB = 21184, kGFF4VFXEmitterVolumeSpawnPrimitiveMeshType = 21185, kGFF4VFXEmitterVolumeSpawnPrimitiveBoxMin = 21186, kGFF4VFXEmitterVolumeSpawnPrimitiveBoxMax = 21187, kGFF4VFXEmitterVolumeSpawnPrimitiveSphereR = 21188, kGFF4VFXEmitterVolumeSpawnPrimitiveCylinderR = 21189, kGFF4VFXEmitterVolumeSpawnPrimitiveCylinderH = 21190, kGFF4VFXEmitterVolumeSpawnPrimitiveCylinderAxis = 21191, kGFF4VFXEmitterVolumeSpawnUseVolumeNormal = 21192, kGFF4VFXEmitterWorldAxisAccelerationX = 21193, kGFF4VFXEmitterWorldAxisAccelerationY = 21194, kGFF4VFXEmitterWorldAxisAccelerationZ = 21195, kGFF4VFXRange = 21196, kGFF4VFXEmitterAxisAccelerationSpace = 21197, kGFF4VFXEmitterUVDistributionsize = 21198, kGFF4VFXEmitterGroupName = 21210, kGFF4VFXRemoteMaterialTintR = 21220, kGFF4VFXRemoteMaterialTintG = 21221, kGFF4VFXRemoteMaterialTintB = 21222, kGFF4VFXRemoteMaterialTintA = 21223, kGFF4VFXRemoteMaterialFresnelFalloff = 21224, kGFF4VFXRemoteMaterialInvertFresnel = 21225, kGFF4VFXRemoteMaterialAlpha = 21226, kGFF4VFXRemoteMaterialDecalName = 21227, kGFF4WndRoot = 22000, kGFF4WndResRef = 22001, kGFF4WndRadius = 22002, kGFF4WndStrength = 22003, kGFF4WndDirection = 22004, kGFF4WndRadiusFalloff = 22005, kGFF4WndGustMinStrength = 22010, kGFF4WndGustMaxStrength = 22011, kGFF4WndGustMinDuration = 22012, kGFF4WndGustMaxDuration = 22013, kGFF4WndGustFrequency = 22014, kGFF4WndTreeNumWindMatrices = 22020, kGFF4WndTreeNumLeafAngles = 22021, kGFF4WndTreeResponse = 22022, kGFF4WndTreeResponseLimit = 22023, kGFF4WndTreeMaxBendAngle = 22024, kGFF4WndTreeBranchExponent = 22025, kGFF4WndTreeLeafExponent = 22026, kGFF4WndTreeBranchOscillationX = 22027, kGFF4WndTreeBranchOscillationY = 22028, kGFF4WndTreeLeafRocking = 22029, kGFF4WndTreeLeafRustling = 22030, kGFF4WndClothResponse = 22031, kGFF4WndClothResponseLmt = 22032, kGFF4WndClothStrength = 22033, kGFF4WndClothGustStrengthMin = 22034, kGFF4WndClothGustStrengthMax = 22035, kGFF4WndClothGustDurationMin = 22036, kGFF4WndClothGustDurationMax = 22037, kGFF4WndClothGustIntervalMin = 22038, kGFF4WndClothGustIntervalMax = 22039, kGFF4WndClothGustDirChange = 22040, kGFF4WndClothGustAxisRatio = 22041, kGFF4AtmoData = 22500, kGFF4AtmoSunColor = 22519, kGFF4AtmoSunIntensity = 22520, kGFF4AtmoTurbidity = 22521, kGFF4AtmoEarthReflectance = 22522, kGFF4AtmoMieMultiplier = 22523, kGFF4AtmoRayleighMultiplier = 22524, kGFF4AtmoEarthInScatterPower = 22525, kGFF4AtmoDistanceMultiplier = 22526, kGFF4AtmoPhaseEccentricity = 22527, kGFF4AtmoAlpha = 22528, kGFF4AtmoFogColor = 22529, kGFF4AtmoFogIntensity = 22530, kGFF4AtmoFogCap = 22531, kGFF4AtmoFogZenith = 22532, kGFF4AtmoFogWaterIntensity = 22533, kGFF4AtmoFogWaterCap = 22534, kGFF4AtmoFogTacticalMultiplier = 22535, kGFF4CloudData = 22600, kGFF4CloudDensity = 22620, kGFF4CloudSharpness = 22621, kGFF4CloudDepth = 22622, kGFF4CloudRangeMultiplier1 = 22623, kGFF4CloudRangeMultiplier2 = 22624, kGFF4CloudColor = 22625, kGFF4MoonScale = 22700, kGFF4MoonAlpha = 22701, kGFF4MoonCloudAlpha = 22702, kGFF4MoonRotation = 22703, kGFF4MorphParts = 23000, kGFF4MorphTintFileNames = 23001, kGFF4MorphNodes = 23002, kGFF4MorphTextureName = 23003, kGFF4MorphTextureParam = 23004, kGFF4MorphVector4fParam = 23005, kGFF4MorphFloatParam = 23006, kGFF4MorphFloatParamValue = 23007, kGFF4MorphName = 23008, kGFF4MorphMatNodeName = 23009, kGFF4MorphMatParamName = 23010, kGFF4MorphMatParamIndex = 23011, kGFF4MorphMatParamValue = 23012, kGFF4MorphMatParamVector = 23013, kGFF4MorphMatParams = 23014, kGFF4MorphMatVecParams = 23015, kGFF4MorphModelName = 23016, kGFF4MorphModelValue = 23017, kGFF4MorphModelParams = 23018, kGFF4MorphTexNodeName = 23019, kGFF4MorphTexParamName = 23020, kGFF4MorphTexName = 23021, kGFF4MorphTextures = 23022, kGFF4MapTag = 24000, kGFF4MapType = 24001, kGFF4MapPinList = 24002, kGFF4MapPinState = 24003, kGFF4MapPinPosX = 24004, kGFF4MapPinPosY = 24005, kGFF4MapPinName = 24006, kGFF4MapPinTag = 24007, kGFF4MapPinAreatag = 24008, kGFF4MapPinTerraintype = 24009, kGFF4MapPinType = 24010, kGFF4MapMaps = 24011, kGFF4MapMapParentResRef = 24012, kGFF4MapPinWaypointOverride = 24013, kGFF4MapTrailList = 24014, kGFF4MapTrailPin1Tag = 24015, kGFF4MapTrailPin2Tag = 24016, kGFF4MapPointList = 24017, kGFF4MapPointPosX = 24018, kGFF4MapPointPosY = 24019, kGFF4MapPinTooltip = 24020, kGFF4DepFileList = 25000, kGFF4DepResRef = 25001, kGFF4DepDependencyList = 25002, kGFF4SaveprofileBuildNumber = 26000, kGFF4SaveprofileInitialBuildNumber = 26001, kGFF4SaveprofileLastUsedProfile = 26002, kGFF4SaveprofileProfileList = 26003, kGFF4SaveprofileAccountName = 26004, kGFF4SaveprofileLocalAchievementData = 26005, kGFF4SaveprofileAchievementList = 26006, kGFF4SaveprofileAchievementID = 26007, kGFF4SaveprofileAchievementNew = 26008, kGFF4SaveprofileAchievementOnline = 26009, kGFF4SaveprofileAchievementCount = 26010, kGFF4SaveprofileAchievementDate = 26011, kGFF4SaveprofileAddinList = 26100, kGFF4SaveprofileOfferList = 26101, kGFF4SaveprofileContentName = 26102, kGFF4SaveprofileContentShown = 26103, kGFF4SaveprofileContentEnabled = 26104, kGFF4SaveprofileContentToken = 26105, kGFF4SaveprofileContentUser = 26106, kGFF4SaveprofileFileList = 26107, kGFF4SaveprofileFileName = 26108, kGFF4SaveprofileFileData = 26109, kGFF4SaveprofileFileVersion = 26110, kGFF4SaveprofileAddinTokenList = 26111, kGFF4MAOFloatName = 33002, kGFF4MAOFloatValue = 33003, kGFF4MAOVectorName = 33004, kGFF4MAOVectorValue = 33005, kGFF4MAOTextureName = 33010, kGFF4MAOTextureResource = 33011, kGFF4MAOMaterial = 33012, kGFF4MAODefaultSemantic = 33013, kGFF4MAOFloats = 33016, kGFF4MAOVectors = 33017, kGFF4MAOTextures = 33020, kGFF4CharMOP = 250100, kGFF4CharApp = 250101, kGFF4CharGender = 250102, kGFF4CharRace = 250103, kGFF4CharClass = 250104, kGFF4CharBack = 250105, kGFF4CharAttributes = 250106, kGFF4CharAbilities = 250107, kGFF4CharName = 250108, kGFF4CharHeadName = 250109, kGFF4CharAttributeID = 250110, kGFF4CharAttributePoints = 250111, kGFF4CharPortrait = 250112 }; } // End of namespace GFF4FieldNamesEnum using namespace GFF4FieldNamesEnum; } // End of namespace Aurora #endif // AURORA_GFF4FIELDS_H xoreos-tools-0.0.5/src/aurora/gff4file.cpp000066400000000000000000001055201331663051500204510ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling version V4.0/V4.1 of BioWare's GFFs (generic file format). */ /* See the GFF description on the Dragon Age toolset wiki * (). */ #include #include "src/common/error.h" #include "src/common/readstream.h" #include "src/common/encoding.h" #include "src/common/strutil.h" #include "src/aurora/gff4file.h" #include "src/aurora/util.h" static const uint32 kGFFID = MKTAG('G', 'F', 'F', ' '); static const uint32 kVersion40 = MKTAG('V', '4', '.', '0'); static const uint32 kVersion41 = MKTAG('V', '4', '.', '1'); namespace Aurora { void GFF4File::Header::read(Common::SeekableReadStream &gff4, uint32 version) { platformID = gff4.readUint32BE(); type = gff4.readUint32BE(); typeVersion = gff4.readUint32BE(); structCount = gff4.readUint32LE(); stringCount = 0; stringOffset = 0xFFFFFFFF; // Only V4.1 has the global string table if (version == kVersion41) { stringCount = gff4.readUint32LE(); stringOffset = gff4.readUint32LE(); } hasSharedStrings = (stringCount > 0) || (stringOffset != 0xFFFFFFFF); dataOffset = gff4.readUint32LE(); } GFF4File::GFF4File(Common::SeekableReadStream *gff4, uint32 type) : _stream(gff4), _topLevelStruct(0) { assert(_stream); load(type); } GFF4File::~GFF4File() { clear(); } void GFF4File::clear() { _stream.reset(); for (StructMap::iterator s = _structs.begin(); s != _structs.end(); ++s) delete s->second; _structs.clear(); _topLevelStruct = 0; } uint32 GFF4File::getType() const { return _header.type; } uint32 GFF4File::getTypeVersion() const { return _header.typeVersion; } uint32 GFF4File::getPlatform() const { return _header.platformID; } const GFF4Struct &GFF4File::getTopLevel() const { assert(_topLevelStruct); return *_topLevelStruct; } // --- Loader --- void GFF4File::load(uint32 type) { try { loadHeader(type); loadStructs(); loadStrings(); } catch (Common::Exception &e) { clear(); e.add("Failed reading GFF4 file"); throw; } } void GFF4File::loadHeader(uint32 type) { readHeader(*_stream); if (_id != kGFFID) throw Common::Exception("Not a GFF4 file"); if ((_version != kVersion40) && (_version != kVersion41)) throw Common::Exception("Unsupported GFF4 file version %s", Common::debugTag(_version).c_str()); _header.read(*_stream, _version); if ((type != 0xFFFFFFFF) && (_header.type != type)) throw Common::Exception("GFF4 has invalid type (want %s, got %s)", Common::debugTag(type).c_str(), Common::debugTag(_header.type).c_str()); if (_header.structCount == 0) throw Common::Exception("GFF4 has no structs"); } void GFF4File::loadStructs() { /* Load the struct templates. * * The struct template defines the structure of a struct, i.e. how * many fields there are and of what type. Each field of a struct type * references one of these templates. When two structs contain the same * structure (but not necessarily the same field *values*), they can * both reference the same struct template. * * So while in a GFF3, each individual struct said how its fields * looked, in a GFF4 this has been sourced out into these templates. */ static const uint32 kStructTemplateSize = 16; const uint32 structTemplateStart = _stream->pos(); _structTemplates.resize(_header.structCount); for (uint32 i = 0; i < _header.structCount; i++) { _stream->seek(structTemplateStart + i * kStructTemplateSize); StructTemplate &strct = _structTemplates[i]; // Read struct properties strct.index = i; strct.label = _stream->readUint32BE(); const uint32 fieldCount = _stream->readUint32LE(); const uint32 fieldOffset = _stream->readUint32LE(); strct.size = _stream->readUint32LE(); // Check if we need to read fields if (fieldOffset == 0xFFFFFFFF) { if (fieldCount != 0) throw Common::Exception("GFF4: fieldOffset NULL, but fieldCount %u", fieldCount); continue; } _stream->seek(fieldOffset); // Read the field declarations strct.fields.resize(fieldCount); for (uint32 j = 0; j < fieldCount; j++) { StructTemplate::Field &field = strct.fields[j]; field.label = _stream->readUint32LE(); field.type = _stream->readUint16LE(); field.flags = _stream->readUint16LE(); field.offset = _stream->readUint32LE(); } } /* And load the top level struct, which itself recurses into field structs. * The top level struct is always constructed using the first template. */ _topLevelStruct = new GFF4Struct(*this, _header.dataOffset, _structTemplates[0]); _topLevelStruct->_refCount++; } void GFF4File::loadStrings() { /* Load the global, shared string table. * * If this GFF4 file has such a table (which is only supported in V4.1), * each individual string field in a struct doesn't provide its own data. * Instead, they then reference this shared string table. */ if (!_header.hasSharedStrings) return; _sharedStrings.resize(_header.stringCount); _stream->seek(_header.stringOffset); for (uint32 i = 0; i < _header.stringCount; i++) _sharedStrings[i] = Common::readString(*_stream, Common::kEncodingUTF8); } // --- Helpers for GFF4Struct --- void GFF4File::registerStruct(uint64 id, GFF4Struct *strct) { /* Each struct, on creation, registers itself to the GFF4 files it * belongs in. * * This is especially necessary for finding reference duplicates: * a struct can be referenced by multiple struct type fields. For * example, let there be structs A, B, C, and D. Structs, A, B and C * can each contain a field "x" of type struct, each linking to * struct D. Moreover, D can even contain field "y" of type struct, * linking back to A, thus creating a loop. */ std::pair result; result = _structs.insert(std::make_pair(id, strct)); if (!result.second) throw Common::Exception("GFF4: Duplicate struct"); } void GFF4File::unregisterStruct(uint64 id) { _structs.erase(id); } GFF4Struct *GFF4File::findStruct(uint64 id) { StructMap::iterator s = _structs.find(id); if (s == _structs.end()) return 0; return s->second; } Common::SeekableReadStream &GFF4File::getStream(uint32 offset) const { _stream->seek(offset); return *_stream; } uint32 GFF4File::getDataOffset() const { return _header.dataOffset; } const GFF4File::StructTemplate &GFF4File::getStructTemplate(uint32 i) const { if (i >= _structTemplates.size()) throw Common::Exception("GFF4: Struct template out of range (%u >= %u)", i, (uint) _structTemplates.size()); return _structTemplates[i]; } bool GFF4File::hasSharedStrings() const { return _header.hasSharedStrings; } Common::UString GFF4File::getSharedString(uint32 i) const { if (i == 0xFFFFFFFF) return ""; if (i >= _sharedStrings.size()) throw Common::Exception("GFF4: Shared string index out of range (%u >= %u)", i, (uint) _sharedStrings.size()); return _sharedStrings[i]; } GFF4Struct::Field::Field() : label(0), type(kFieldTypeNone), offset(0xFFFFFFFF), isList(false), isReference(false), isGeneric(false), structIndex(0) { } GFF4Struct::Field::Field(uint32 l, uint16 t, uint16 f, uint32 o, bool g) : label(l), offset(o), isGeneric(g) { isList = (f & 0x8000) != 0; isReference = (f & 0x2000) != 0; // Map the struct flag to the struct type and index, if necessary const bool isStruct = (f & 0x4000) != 0; if (isStruct) { type = kFieldTypeStruct; structIndex = t; } else { type = (FieldType) t; structIndex = 0; } // A string is always read by reference. An extra reference flag is superfluous. if (type == kFieldTypeString) isReference = false; bool supportedConfig = true; // We don't know how any of these work if (isList && (type == kFieldTypeASCIIString)) supportedConfig = false; if (isList && (type == kFieldTypeTlkString)) supportedConfig = false; if (isList && isReference && (type != kFieldTypeStruct) && (type != kFieldTypeGeneric)) supportedConfig = false; if (isList && !isReference && (type == kFieldTypeGeneric)) supportedConfig = false; if (!supportedConfig) throw Common::Exception("GFF4: TODO: Field type %d, isList %d, isReference %d", (int) type, isList, isReference); } GFF4Struct::Field::~Field() { } GFF4Struct::GFF4Struct(GFF4File &parent, uint32 offset, const GFF4File::StructTemplate &tmplt) : _parent(&parent), _label(tmplt.label), _refCount(0), _fieldCount(0) { // Constructor for a real struct, from a template _id = generateID(offset, &tmplt); parent.registerStruct(_id, this); try { load(parent, offset, tmplt); } catch (...) { parent.unregisterStruct(_id); throw; } } GFF4Struct::GFF4Struct(GFF4File &parent, const Field &genericParent) : _parent(&parent), _label(0), _refCount(0), _fieldCount(0) { // Constructor for a generic, converted into a struct _id = generateID(genericParent.offset); parent.registerStruct(_id, this); try { load(parent, genericParent); } catch (...) { parent.unregisterStruct(_id); throw; } } GFF4Struct::~GFF4Struct() { } uint64 GFF4Struct::getID() const { return _id; } uint32 GFF4Struct::getRefCount() const { return _refCount; } uint32 GFF4Struct::getLabel() const { return _label; } // --- Loader --- void GFF4Struct::load(GFF4File &parent, uint32 offset, const GFF4File::StructTemplate &tmplt) { /* Loader for a real struct, from a template. * * Go through all the fields in the template and create field * instances within this struct instance. If the field is itself * a struct, recursively create a new struct instance for it. If * the field is a generic, create a struct for it as well. */ for (size_t i = 0; i < tmplt.fields.size(); i++) { const GFF4File::StructTemplate::Field &field = tmplt.fields[i]; _fieldLabels.push_back(field.label); // Calculate the offset for the field data, but guard against NULL pointers uint32 fieldOffset = offset + field.offset; if ((offset == 0xFFFFFFFF) || (field.offset == 0xFFFFFFFF)) fieldOffset = 0xFFFFFFFF; // Load the field and its struct(s), if any Field &f = _fields[field.label] = Field(field.label, field.type, field.flags, fieldOffset); if (f.type == kFieldTypeStruct) loadStructs(parent, f); if (f.type == kFieldTypeGeneric) loadGeneric(parent, f); if ((f.type == kFieldTypeASCIIString) && parent.hasSharedStrings()) throw Common::Exception("GFF4: TODO: ASCII string field in a file with shared strings"); } _fieldCount = _fields.size(); } void GFF4Struct::loadStructs(GFF4File &parent, Field &field) { if (field.offset == 0xFFFFFFFF) return; /* Loader for fields of struct type. * * This field can be * a) a list of structs * b) a reference (pointer) to a struct * c) both * * We figure out how many structs there are (1 if not a list), * where the offset is (dependent on whether it's a reference) * and then we load every single one of them. However, we also * ask the parent GFF4 if we already have loaded the struct in * question (which can happen, because more than one reference * can point to the same struct). If that is the case, we don't * need to load it again. */ const GFF4File::StructTemplate &tmplt = parent.getStructTemplate(field.structIndex); Common::SeekableReadStream &data = parent.getStream(field.offset); const uint32 structCount = getListCount(data, field); const uint32 structSize = field.isReference ? 4 : tmplt.size; const uint32 structStart = data.pos(); field.structs.resize(structCount, 0); for (uint32 i = 0; i < structCount; i++) { const uint32 offset = getDataOffset(field.isReference, structStart + i * structSize); if (offset == 0xFFFFFFFF) continue; GFF4Struct *strct = parent.findStruct(generateID(offset, &tmplt)); if (!strct) strct = new GFF4Struct(parent, offset, tmplt); strct->_refCount++; field.structs[i] = strct; } } void GFF4Struct::loadGeneric(GFF4File &parent, Field &field) { field.offset = getDataOffset(field.isList, field.offset); if (field.offset == 0xFFFFFFFF) return; // Loader for fields of generic type. We map the generic to a struct. GFF4Struct *strct = parent.findStruct(generateID(field.offset)); if (!strct) strct = new GFF4Struct(parent, field); strct->_refCount++; field.structs.push_back(strct); } void GFF4Struct::load(GFF4File &parent, const Field &genericParent) { /* Loader for generic, converting it into a struct. * * Go through all the elements of the generic and create fields * for them in this struct instance. If the element itself is a * struct, recursively create a new struct instance for it. */ static const uint32 kGenericSize = 8; Common::SeekableReadStream &data = parent.getStream(genericParent.offset); const uint32 genericCount = genericParent.isList ? data.readUint32LE() : 1; const uint32 genericStart = data.pos(); for (uint32 i = 0; i < genericCount; i++) { data.seek(genericStart + i * kGenericSize); const uint16 fieldType = data.readUint16LE(); const uint16 fieldFlags = data.readUint16LE(); const uint32 fieldOffset = getDataOffset(genericParent.isReference, data.pos()); if (fieldOffset == 0xFFFFFFFF) continue; _fieldLabels.push_back(i); // Load the field and its struct(s), if any Field &f = _fields[i] = Field(i, fieldType, fieldFlags, fieldOffset, true); if (f.type == kFieldTypeStruct) loadStructs(parent, f); if (f.type == kFieldTypeGeneric) throw Common::Exception("GFF4: Found a generic with type generic?"); if ((f.type == kFieldTypeASCIIString) && parent.hasSharedStrings()) throw Common::Exception("GFF4: TODO: ASCII string field in a file with shared strings"); } _fieldCount = genericCount; } uint64 GFF4Struct::generateID(uint32 offset, const GFF4File::StructTemplate *tmplt) { /* Generate a unique ID identifying this struct within the GFF4 file. * The offset is an obvious choice. We also add the template index, * just to make sure. * * (However, if this struct is actually a mapped generic, there is * no template index). */ return (((uint64) offset) << 32) | (tmplt ? tmplt->index : 0xFFFFFFFF); } // --- Field properties --- size_t GFF4Struct::getFieldCount() const { return _fieldCount; } bool GFF4Struct::hasField(uint32 field) const { return getField(field) != 0; } const std::vector &GFF4Struct::getFieldLabels() const { return _fieldLabels; } GFF4Struct::FieldType GFF4Struct::getFieldType(uint32 field) const { bool isList; return getFieldType(field, isList); } GFF4Struct::FieldType GFF4Struct::getFieldType(uint32 field, bool &isList) const { const Field *f = getField(field); if (!f) return kFieldTypeNone; isList = f->isList; return f->type; } bool GFF4Struct::getFieldProperties(uint32 field, FieldType &type, uint32 &label, bool &isList) const { const Field *f = getField(field); if (!f) return false; type = f->type; label = f->label; isList = f->isList; return true; } // --- Field value reader helpers --- const GFF4Struct::Field *GFF4Struct::getField(uint32 field) const { FieldMap::const_iterator f = _fields.find(field); if (f == _fields.end()) return 0; return &f->second; } uint32 GFF4Struct::getDataOffset(bool isReference, uint32 offset) const { if (!isReference || (offset == 0xFFFFFFFF)) return offset; Common::SeekableReadStream &data = _parent->getStream(offset); offset = data.readUint32LE(); if (offset == 0xFFFFFFFF) return offset; return _parent->getDataOffset() + offset; } uint32 GFF4Struct::getDataOffset(const Field &field) const { if (field.type == kFieldTypeStruct) return 0xFFFFFFFF; return getDataOffset(field.isReference, field.offset); } Common::SeekableReadStream *GFF4Struct::getData(const Field &field) const { const uint32 offset = getDataOffset(field); if (offset == 0xFFFFFFFF) return 0; return &_parent->getStream(offset); } Common::SeekableReadStream *GFF4Struct::getField(uint32 fieldID, const Field *&field) const { if (!(field = getField(fieldID))) return 0; return getData(*field); } uint32 GFF4Struct::getVectorMatrixLength(const Field &field, uint32 minLength, uint32 maxLength) const { uint32 length; if (field.type == kFieldTypeVector3f) length = 3; else if ((field.type == kFieldTypeVector4f) || (field.type == kFieldTypeQuaternionf) || (field.type == kFieldTypeColor4f)) length = 4; else if (field.type == kFieldTypeMatrix4x4f) length = 16; else throw Common::Exception("GFF4: Field is not of Vector/Matrix type"); if (length < minLength) throw Common::Exception("GFF4: Vector/Matrix type is too short (%d < %d)", length, minLength); if (length > maxLength) throw Common::Exception("GFF4: Vector/Matrix type is too long (%d > %d)", length, maxLength); return length; } uint32 GFF4Struct::getListCount(Common::SeekableReadStream &data, const Field &field) const { if (!field.isList) return 1; const uint32 listOffset = data.readUint32LE(); if (listOffset == 0xFFFFFFFF) return 0; data.seek(_parent->getDataOffset() + listOffset); return data.readUint32LE(); } uint32 GFF4Struct::getFieldSize(FieldType type) const { switch (type) { case kFieldTypeUint8: case kFieldTypeSint8: return 1; case kFieldTypeUint16: case kFieldTypeSint16: return 2; case kFieldTypeUint32: case kFieldTypeSint32: case kFieldTypeFloat32: return 4; case kFieldTypeUint64: case kFieldTypeSint64: case kFieldTypeFloat64: return 8; case kFieldTypeVector3f: return 3 * 4; case kFieldTypeVector4f: case kFieldTypeQuaternionf: case kFieldTypeColor4f: return 4 * 4; case kFieldTypeMatrix4x4f: return 16 * 4; case kFieldTypeTlkString: return 2 * 4; case kFieldTypeString: // The raw form is a pointer... return 4; case kFieldTypeASCIIString: // Actually depending on the content... return 4; default: break; } return 0; } // --- Low-level value readers --- uint64 GFF4Struct::getUint(Common::SeekableReadStream &data, FieldType type) const { switch (type) { case kFieldTypeUint8: return (uint64) data.readByte(); case kFieldTypeSint8: return (uint64) ((int64) data.readSByte()); case kFieldTypeUint16: return (uint64) data.readUint16LE(); case kFieldTypeSint16: return (uint64) ((int64) data.readSint16LE()); case kFieldTypeUint32: return (uint64) data.readUint32LE(); case kFieldTypeSint32: return (uint64) ((int64) data.readSint32LE()); case kFieldTypeUint64: return (uint64) data.readUint64LE(); case kFieldTypeSint64: return (uint64) ((int64) data.readSint64LE()); default: break; } throw Common::Exception("GFF4: Field is not an int type"); } int64 GFF4Struct::getSint(Common::SeekableReadStream &data, FieldType type) const { switch (type) { case kFieldTypeUint8: return (int64) ((uint64) data.readByte()); case kFieldTypeSint8: return (int64) data.readSByte(); case kFieldTypeUint16: return (int64) ((uint64) data.readUint16LE()); case kFieldTypeSint16: return (int64) data.readSint16LE(); case kFieldTypeUint32: return (int64) ((uint64) data.readUint32LE()); case kFieldTypeSint32: return (int64) data.readSint32LE(); case kFieldTypeUint64: return (int64) ((uint64) data.readUint64LE()); case kFieldTypeSint64: return (int64) data.readSint64LE(); default: break; } throw Common::Exception("GFF4: Field is not an int type"); } double GFF4Struct::getDouble(Common::SeekableReadStream &data, FieldType type) const { switch (type) { case kFieldTypeFloat32: return (double) data.readIEEEFloatLE(); case kFieldTypeFloat64: return (double) data.readIEEEDoubleLE(); case kFieldTypeNDSFixed: return readNintendoFixedPoint(data.readUint32LE(), true, 19, 12); default: break; } throw Common::Exception("GFF4: Field is not a float type"); } float GFF4Struct::getFloat(Common::SeekableReadStream &data, FieldType type) const { switch (type) { case kFieldTypeFloat32: return (float) data.readIEEEFloatLE(); case kFieldTypeFloat64: return (float) data.readIEEEDoubleLE(); case kFieldTypeNDSFixed: return (float) readNintendoFixedPoint(data.readUint32LE(), true, 19, 12); default: break; } throw Common::Exception("GFF4: Field is not a float type"); } Common::UString GFF4Struct::getString(Common::SeekableReadStream &data, Common::Encoding encoding) const { /* When the string is encoded in UTF-8, then length field specifies the length in bytes. * Otherwise, it's the length in characters. */ const size_t lengthMult = encoding == Common::kEncodingUTF8 ? 1 : Common::getBytesPerCodepoint(encoding); const size_t offset = data.pos(); const uint32 length = data.readUint32LE(); const size_t size = length * lengthMult; try { return Common::readStringFixed(data, encoding, size); } catch (...) { } return Common::UString::format("GFF4: Invalid string encoding (0x%08X)", (uint) offset); } Common::UString GFF4Struct::getString(Common::SeekableReadStream &data, Common::Encoding encoding, uint32 offset) const { const uint32 pos = data.seek(offset); Common::UString str = getString(data, encoding); data.seek(pos); return str; } Common::UString GFF4Struct::getString(Common::SeekableReadStream &data, const Field &field, Common::Encoding encoding) const { if (field.type == kFieldTypeString) { if (_parent->hasSharedStrings()) return _parent->getSharedString(data.readUint32LE()); uint32 offset = data.pos(); if (!field.isGeneric) { offset = data.readUint32LE(); if (offset == 0xFFFFFFFF) return ""; offset += _parent->getDataOffset(); } return getString(data, encoding, offset); } if (field.type == kFieldTypeASCIIString) return getString(data, Common::kEncodingASCII, data.pos()); throw Common::Exception("GFF4: Field is not a string type"); } // --- Single value readers --- uint64 GFF4Struct::getUint(uint32 field, uint64 def) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return def; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); return getUint(*data, f->type); } int64 GFF4Struct::getSint(uint32 field, int64 def) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return def; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); return getSint(*data, f->type); } bool GFF4Struct::getBool(uint32 field, bool def) const { return getUint(field, def) != 0; } double GFF4Struct::getDouble(uint32 field, double def) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return def; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); return getDouble(*data, f->type); } float GFF4Struct::getFloat(uint32 field, float def) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return def; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); return getFloat(*data, f->type); } Common::UString GFF4Struct::getString(uint32 field, Common::Encoding encoding, const Common::UString &def) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return def; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); return getString(*data, *f, encoding); } Common::UString GFF4Struct::getString(uint32 field, const Common::UString &def) const { return getString(field, Common::kEncodingUTF16LE, def); } bool GFF4Struct::getTalkString(uint32 field, Common::Encoding encoding, uint32 &strRef, Common::UString &str) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->type != kFieldTypeTlkString) throw Common::Exception("GFF4: Field is not of TalkString type"); if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); strRef = getUint(*data, kFieldTypeUint32); const uint32 offset = getUint(*data, kFieldTypeUint32); str.clear(); if (offset != 0xFFFFFFFF) { if (_parent->hasSharedStrings()) str = _parent->getSharedString(offset); else if (offset != 0) str = getString(*data, encoding, _parent->getDataOffset() + offset); } return true; } bool GFF4Struct::getTalkString(uint32 field, uint32 &strRef, Common::UString &str) const { return getTalkString(field, Common::kEncodingUTF16LE, strRef, str); } bool GFF4Struct::getVector3(uint32 field, double &v1, double &v2, double &v3) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); getVectorMatrixLength(*f, 3, 3); v1 = getDouble(*data, kFieldTypeFloat32); v2 = getDouble(*data, kFieldTypeFloat32); v3 = getDouble(*data, kFieldTypeFloat32); return true; } bool GFF4Struct::getVector3(uint32 field, float &v1, float &v2, float &v3) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); getVectorMatrixLength(*f, 3, 3); v1 = getFloat(*data, kFieldTypeFloat32); v2 = getFloat(*data, kFieldTypeFloat32); v3 = getFloat(*data, kFieldTypeFloat32); return true; } bool GFF4Struct::getVector4(uint32 field, double &v1, double &v2, double &v3, double &v4) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); getVectorMatrixLength(*f, 4, 4); v1 = getDouble(*data, kFieldTypeFloat32); v2 = getDouble(*data, kFieldTypeFloat32); v3 = getDouble(*data, kFieldTypeFloat32); v4 = getDouble(*data, kFieldTypeFloat32); return true; } bool GFF4Struct::getVector4(uint32 field, float &v1, float &v2, float &v3, float &v4) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); getVectorMatrixLength(*f, 4, 4); v1 = getFloat(*data, kFieldTypeFloat32); v2 = getFloat(*data, kFieldTypeFloat32); v3 = getFloat(*data, kFieldTypeFloat32); v4 = getFloat(*data, kFieldTypeFloat32); return true; } bool GFF4Struct::getMatrix4x4(uint32 field, double (&m)[16]) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); const uint32 length = getVectorMatrixLength(*f, 16, 16); for (uint32 i = 0; i < length; i++) m[i] = getDouble(*data, kFieldTypeFloat32); return true; } bool GFF4Struct::getMatrix4x4(uint32 field, float (&m)[16]) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); const uint32 length = getVectorMatrixLength(*f, 16, 16); for (uint32 i = 0; i < length; i++) m[i] = getFloat(*data, kFieldTypeFloat32); return true; } bool GFF4Struct::getVectorMatrix(uint32 field, std::vector &vectorMatrix) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); const uint32 length = getVectorMatrixLength(*f, 0, 16); vectorMatrix.resize(length); for (uint32 i = 0; i < length; i++) vectorMatrix[i] = getDouble(*data, kFieldTypeFloat32); return true; } bool GFF4Struct::getVectorMatrix(uint32 field, std::vector &vectorMatrix) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); const uint32 length = getVectorMatrixLength(*f, 0, 16); vectorMatrix.resize(length); for (uint32 i = 0; i < length; i++) vectorMatrix[i] = getFloat(*data, kFieldTypeFloat32); return true; } // --- List value readers --- bool GFF4Struct::getUint(uint32 field, std::vector &list) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; const uint32 count = getListCount(*data, *f); list.resize(count); for (uint32 i = 0; i < count; i++) list[i] = getUint(*data, f->type); return true; } bool GFF4Struct::getSint(uint32 field, std::vector &list) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; const uint32 count = getListCount(*data, *f); list.resize(count); for (uint32 i = 0; i < count; i++) list[i] = getSint(*data, f->type); return true; } bool GFF4Struct::getBool(uint32 field, std::vector &list) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; const uint32 count = getListCount(*data, *f); list.resize(count); for (uint32 i = 0; i < count; i++) list[i] = getUint(*data, f->type) != 0; return true; } bool GFF4Struct::getDouble(uint32 field, std::vector &list) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; const uint32 count = getListCount(*data, *f); list.resize(count); for (uint32 i = 0; i < count; i++) list[i] = getDouble(*data, f->type); return true; } bool GFF4Struct::getFloat(uint32 field, std::vector &list) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; const uint32 count = getListCount(*data, *f); list.resize(count); for (uint32 i = 0; i < count; i++) list[i] = getFloat(*data, f->type); return true; } bool GFF4Struct::getString(uint32 field, Common::Encoding encoding, std::vector &list) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) { if (f && !f->isList) { list.push_back(""); return true; } return false; } const uint32 count = getListCount(*data, *f); list.resize(count); for (uint32 i = 0; i < count; i++) list[i] = getString(*data, *f, encoding); return true; } bool GFF4Struct::getString(uint32 field, std::vector &list) const { return getString(field, Common::kEncodingUTF16LE, list); } bool GFF4Struct::getTalkString(uint32 field, Common::Encoding encoding, std::vector &strRefs, std::vector &strs) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; if (f->type != kFieldTypeTlkString) throw Common::Exception("GFF4: Field is not of TalkString type"); const uint32 count = getListCount(*data, *f); strRefs.resize(count); strs.resize(count); std::vector offsets; offsets.resize(count); for (uint32 i = 0; i < count; i++) { strRefs[i] = getUint(*data, kFieldTypeUint32); const uint32 offset = getUint(*data, kFieldTypeUint32); if (offset != 0xFFFFFFFF) { if (_parent->hasSharedStrings()) strs[i] = _parent->getSharedString(offset); else if (offset != 0) strs[i] = getString(*data, encoding, _parent->getDataOffset() + offset); } } return true; } bool GFF4Struct::getTalkString(uint32 field, std::vector &strRefs, std::vector &strs) const { return getTalkString(field, Common::kEncodingUTF16LE, strRefs, strs); } bool GFF4Struct::getVectorMatrix(uint32 field, std::vector< std::vector > &list) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; const uint32 length = getVectorMatrixLength(*f, 0, 16); const uint32 count = getListCount(*data, *f); list.resize(count); for (uint32 i = 0; i < count; i++) { list[i].resize(length); for (uint32 j = 0; j < length; j++) list[i][j] = getDouble(*data, kFieldTypeFloat32); } return true; } bool GFF4Struct::getVectorMatrix(uint32 field, std::vector< std::vector > &list) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return false; const uint32 length = getVectorMatrixLength(*f, 0, 16); const uint32 count = getListCount(*data, *f); list.resize(count); for (uint32 i = 0; i < count; i++) { list[i].resize(length); for (uint32 j = 0; j < length; j++) list[i][j] = getFloat(*data, kFieldTypeFloat32); } return true; } // --- Struct reader --- const GFF4Struct *GFF4Struct::getStruct(uint32 field) const { const Field *f = getField(field); if (!f) return 0; if (f->type != kFieldTypeStruct) throw Common::Exception("GFF4: Field is not of struct type"); if (f->isList) throw Common::Exception("GFF4: Tried reading list as singular value"); if (!f->structs.empty()) return f->structs[0]; return 0; } // --- Generic reader --- const GFF4Struct *GFF4Struct::getGeneric(uint32 field) const { const Field *f = getField(field); if (!f) return 0; if (f->type != kFieldTypeGeneric) throw Common::Exception("GFF4: Field is not of generic type"); if (!f->structs.empty()) return f->structs[0]; return 0; } // --- Struct list reader --- const GFF4List &GFF4Struct::getList(uint32 field) const { const Field *f = getField(field); if (!f) throw Common::Exception("GFF4: No such field"); if (f->type != kFieldTypeStruct) throw Common::Exception("GFF4: Field is not of struct type"); return f->structs; } // --- Struct data reader --- Common::SeekableReadStream *GFF4Struct::getData(uint32 field) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return 0; const uint32 count = getListCount(*data, *f); const uint32 size = getFieldSize(f->type); if ((size == 0) || (count == 0)) return 0; const size_t dataSize = count * size; const size_t dataBegin = data->pos(); const size_t dataEnd = data->pos() + dataSize; if ((dataBegin >= data->size()) || ((data->size() - dataBegin) < dataSize)) throw Common::Exception("Invalid data offset (%u, %u, %u)", (uint) dataBegin, (uint) dataSize, (uint) data->size()); return new Common::SeekableSubReadStream(data, dataBegin, dataEnd); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/gff4file.h000066400000000000000000000360751331663051500201260ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling version V4.0/V4.1 of BioWare's GFFs (generic file format). */ #ifndef AURORA_GFF4FILE_H #define AURORA_GFF4FILE_H #include #include #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/ustring.h" #include "src/common/encoding.h" #include "src/aurora/types.h" #include "src/aurora/aurorafile.h" #include "src/aurora/gff4fields.h" namespace Common { class SeekableReadStream; } namespace Aurora { class GFF4Struct; /** A GFF (generic file format) V4.0/V4.1 file, found in Dragon Age: Origins, * Dragon Age 2 and Sonic Chronicles: The Dark Brotherhood. * * Just like GFF V3.2/V3.3 files, GFF V4.0/V4.1 store hierarchical data, * similar in concept to XML and hold, for example, module and campaign * descriptions. Unlike version 3 of the format, version 4 is optimized * for access speed, with fields indexed by a numerical value instead of * a human-readable string. A collection of currently known field values * and their meanings can be found in gff4fields.h. * * Unlike GFF3, GFF4 has a new concept, the generic. A generic is a field * of variable type. I.e. a field can contain any other type. A list of * generics can even contain different types at different indices. * * GFF V4.0/V4.1 files come in a multitude of types (ARE, DLG, ...), each * with its own 4-byte type ID ('ARE ', 'DLG ', ...). When specified in * the GFF4File constructor, the loader will enforce that it matches, and * throw an exception should it not. Conversely, an ID of 0xFFFFFFFF means * that no such type ID enforcement should be done. In both cases, the type * ID read from the file can get access through getType(). * * GFF V4.1 files exclusively appear in Dragon Age 2 (but Dragon Age 2 also * has GFF V4.0 files). The only difference between these versions is that * V4.1 has support for a global string table and every string field can * reference a string within this table, so that duplicated strings don't * need to be stored multiple times. * * Notes: * - Generics and lists of generics are mapped to structs, with the field ID * being the list element indices (or just 0 on non-list generics). * - Strings are generally encoded in UTF-16LE. One exception is the TLK files * in Sonic, which have strings in a language-specific encoding. For example, * the English, French, Italian, German and Spanish (EFIGS) versions have * the strings in TLK files encoded in Windows CP-1252. * * See also: GFF3File in gff3file.h for the earlier V3.2/V3.3 versions of * the GFF format. */ class GFF4File : boost::noncopyable, public AuroraFile { public: /** Take over this stream and read a GFF4 file out of it. */ GFF4File(Common::SeekableReadStream *gff4, uint32 type = 0xFFFFFFFF); ~GFF4File(); /** Return the GFF4's specific type. */ uint32 getType() const; /** Return the GFF4's specific type version. */ uint32 getTypeVersion() const; /** Return the platform this GFF4 is for. */ uint32 getPlatform() const; /** Returns the top-level struct. */ const GFF4Struct &getTopLevel() const; private: /** A GFF4 header. */ struct Header { uint32 platformID; ///< ID of the platform this GFF4 is for. uint32 type; ///< The specific type this GFF4 describes. uint32 typeVersion; ///< The version of the specific type this GFF4 describes. uint32 structCount; ///< Number of struct templates in this GFF4. uint32 stringCount; ///< Number of shared strings (V4.1 only). uint32 stringOffset; ///< Offset to shared strings (V4.1 only). uint32 dataOffset; ///< Offset to the data portion. bool hasSharedStrings; void read(Common::SeekableReadStream &gff4, uint32 version); }; /** A template of a struct, used when loading a struct. */ struct StructTemplate { struct Field { uint32 label; uint16 type; uint16 flags; uint32 offset; }; uint32 index; uint32 label; uint32 size; std::vector fields; }; typedef std::vector StructTemplates; typedef std::vector SharedStrings; typedef std::map StructMap; Common::ScopedPtr _stream; /** This GFF4's header. */ Header _header; /** All struct templates in this GFF4. */ StructTemplates _structTemplates; /** The shared strings used in V4.1. */ SharedStrings _sharedStrings; /** All actual structs in this GFF4. */ StructMap _structs; /** The top-level struct. */ GFF4Struct *_topLevelStruct; // .--- Loading helpers void load(uint32 type); void loadHeader(uint32 type); void loadStructs(); void loadStrings(); void clear(); // '--- // .--- Helper methods called by GFF4Struct void registerStruct(uint64 id, GFF4Struct *strct); void unregisterStruct(uint64 id); GFF4Struct *findStruct(uint64 id); Common::SeekableReadStream &getStream(uint32 offset) const; const StructTemplate &getStructTemplate(uint32 i) const; uint32 getDataOffset() const; bool hasSharedStrings() const; Common::UString getSharedString(uint32 i) const; // '--- friend class GFF4Struct; }; class GFF4Struct { public: /** The type of a GFF4 field. */ enum FieldType { kFieldTypeNone = - 1, ///< Invalid type. kFieldTypeUint8 = 0, ///< Unsigned 8bit integer. kFieldTypeSint8 = 1, ///< Signed 8bit integer. kFieldTypeUint16 = 2, ///< Unsigned 16bit integer. kFieldTypeSint16 = 3, ///< Signed 16bit integer. kFieldTypeUint32 = 4, ///< Unsigned 32bit integer. kFieldTypeSint32 = 5, ///< Signed 32bit integer. kFieldTypeUint64 = 6, ///< Unsigned 64bit integer. kFieldTypeSint64 = 7, ///< Signed 64bit integer. kFieldTypeFloat32 = 8, ///< 32bit IEEE float. kFieldTypeFloat64 = 9, ///< 64bit IEEE float (double). kFieldTypeVector3f = 10, ///< 3 IEEE floats, 3D vector. kFieldTypeVector4f = 12, ///< 4 IEEE floats, 4D vector. kFieldTypeQuaternionf = 13, ///< 4 IEEE floats, Quaternion rotation. kFieldTypeString = 14, ///< A string. kFieldTypeColor4f = 15, ///< 4 IEEE floats, RGBA color. kFieldTypeMatrix4x4f = 16, ///< 16 IEEE floats, 4x4 matrix in row-major order. kFieldTypeTlkString = 17, ///< 2 unsigned 32bit integers, reference into the TLK table. kFieldTypeNDSFixed = 18, ///< A 32bit fixed-point value, found in Sonic. kFieldTypeASCIIString = 20, ///< ASCII string, found in Sonic. kFieldTypeStruct = 65534, ///< A struct. kFieldTypeGeneric = 65535 ///< A "generic" field, able to hold any other type. }; /** Return the struct's unique ID within the GFF4. */ uint64 getID() const; /** Return the number of structs that refer to this struct. */ uint32 getRefCount() const; /** Return the struct's label. * * The label is a (non-unique) 4-byte value, most often consisting of * upper-case letters ([A-Z]), that can sometimes be used to identify * the higher-level meaning of a struct within a GFF4. * * It is read as a big-endian 32-bit integer value. See the MKTAG() * macro, as defined in src/common/endianness.h, for generating values * to compare it against. * * The purpose of the label in a GFF4 struct is comparable to the ID in * a GFF3 struct. */ uint32 getLabel() const; /** Return the number of fields in this struct. */ size_t getFieldCount() const; /** Does this specific field exist? */ bool hasField(uint32 field) const; /** Return a list of all field labels in this struct. */ const std::vector &getFieldLabels() const; /** Return the type of this field, or kFieldTypeNone if it doesn't exist. */ FieldType getFieldType(uint32 field) const; /** Return the type of this field and whether it's list, or kFieldTypeNone if it doesn't exist. */ FieldType getFieldType(uint32 field, bool &isList) const; /** Collectively return all field properties in one go. * * @return true if the field exists, false otherwise. */ bool getFieldProperties(uint32 field, FieldType &type, uint32 &label, bool &isList) const; // .--- Single values uint64 getUint(uint32 field, uint64 def = 0 ) const; int64 getSint(uint32 field, int64 def = 0 ) const; bool getBool(uint32 field, bool def = false) const; double getDouble(uint32 field, double def = 0.0 ) const; float getFloat (uint32 field, float def = 0.0f) const; /** Return a field string, read from the given encoding. */ Common::UString getString(uint32 field, Common::Encoding encoding, const Common::UString &def = "") const; /** Return a field string, read from the default UTF-16LE encoding. */ Common::UString getString(uint32 field, const Common::UString &def = "") const; /** Return a talk string, which is a reference into the TalkTable and an optional direct string. */ bool getTalkString(uint32 field, Common::Encoding encoding, uint32 &strRef, Common::UString &str) const; /** Return a talk string, which is a reference into the TalkTable and an optional direct string. */ bool getTalkString(uint32 field, uint32 &strRef, Common::UString &str) const; bool getVector3(uint32 field, double &v1, double &v2, double &v3) const; bool getVector4(uint32 field, double &v1, double &v2, double &v3, double &v4) const; bool getMatrix4x4(uint32 field, double (&m)[16]) const; bool getVector3(uint32 field, float &v1, float &v2, float &v3) const; bool getVector4(uint32 field, float &v1, float &v2, float &v3, float &v4) const; bool getMatrix4x4(uint32 field, float (&m)[16]) const; /** Return a field vector or a matrix type as a std::vector of doubles. */ bool getVectorMatrix(uint32 field, std::vector &vectorMatrix) const; /** Return a field vector or a matrix type as a std::vector of doubles. */ bool getVectorMatrix(uint32 field, std::vector &vectorMatrix) const; // '--- // .--- Lists of values bool getUint(uint32 field, std::vector &list) const; bool getSint(uint32 field, std::vector< int64> &list) const; bool getBool(uint32 field, std::vector &list) const; bool getDouble(uint32 field, std::vector &list) const; bool getFloat (uint32 field, std::vector &list) const; /** Return field strings, read from the given encoding. */ bool getString(uint32 field, Common::Encoding encoding, std::vector &list) const; /** Return field strings, read from the default UTF-16LE encoding. */ bool getString(uint32 field, std::vector &list) const; /** Return field talk strings. */ bool getTalkString(uint32 field, Common::Encoding encoding, std::vector &strRefs, std::vector &strs) const; /** Return field talk strings. */ bool getTalkString(uint32 field, std::vector &strRefs, std::vector &strs) const; /** Return field vector or a matrix types as std::vectors of doubles. */ bool getVectorMatrix(uint32 field, std::vector< std::vector > &list) const; /** Return field vector or a matrix types as std::vectors of floats. */ bool getVectorMatrix(uint32 field, std::vector< std::vector > &list) const; // '--- // .--- Structs and lists of structs const GFF4Struct *getStruct (uint32 field) const; const GFF4Struct *getGeneric(uint32 field) const; const GFF4List &getList (uint32 field) const; // '--- // .--- Raw data /** Return the raw data of the field as a Seekable(Sub)ReadStream. Dangerous. */ Common::SeekableReadStream *getData(uint32 field) const; // '--- private: /** A field in the GFF4 struct. */ struct Field { uint32 label; ///< A numerical label of the field. FieldType type; ///< Type of the field. uint32 offset; ///< Offset into the GFF4 data. bool isList; ///< Is this field a singular item or a list? bool isReference; ///< Is this field a reference (pointer) to another field? bool isGeneric; ///< Is this field found in a generic? uint16 structIndex; ///< Index of the field's struct type (if kFieldTypeStruct). GFF4List structs; ///< List of GFF4Struct (if kFieldTypeStruct). Field(); Field(uint32 l, uint16 t, uint16 f, uint32 o, bool g = false); ~Field(); }; typedef std::map FieldMap; const GFF4File *_parent; uint32 _label; uint64 _id; uint32 _refCount; size_t _fieldCount; FieldMap _fields; /** The labels of all fields in this struct. */ std::vector _fieldLabels; // .--- Loader /** Load a GFF4 struct. */ GFF4Struct(GFF4File &parent, uint32 offset, const GFF4File::StructTemplate &tmplt); /** Load a GFF4 generic as a struct. */ GFF4Struct(GFF4File &parent, const Field &genericParent); ~GFF4Struct(); void load(GFF4File &parent, uint32 offset, const GFF4File::StructTemplate &tmplt); void loadStructs(GFF4File &parent, Field &field); void loadGeneric(GFF4File &parent, Field &field); void load(GFF4File &parent, const Field &genericParent); static uint64 generateID(uint32 offset, const GFF4File::StructTemplate *tmplt = 0); // '--- // .--- Field and field data accessors const Field *getField(uint32 field) const; uint32 getDataOffset(bool isReference, uint32 offset) const; uint32 getDataOffset(const Field &field) const; Common::SeekableReadStream *getData(const Field &field) const; Common::SeekableReadStream *getField(uint32 fieldID, const Field *&field) const; // '--- // .--- Field reader helpers uint32 getListCount(Common::SeekableReadStream &data, const Field &field) const; uint32 getFieldSize(FieldType type) const; uint64 getUint(Common::SeekableReadStream &data, FieldType type) const; int64 getSint(Common::SeekableReadStream &data, FieldType type) const; double getDouble(Common::SeekableReadStream &data, FieldType type) const; float getFloat (Common::SeekableReadStream &data, FieldType type) const; Common::UString getString(Common::SeekableReadStream &data, Common::Encoding encoding) const; Common::UString getString(Common::SeekableReadStream &data, Common::Encoding encoding, uint32 offset) const; Common::UString getString(Common::SeekableReadStream &data, const Field &field, Common::Encoding encoding) const; uint32 getVectorMatrixLength(const Field &field, uint32 minLength, uint32 maxLength) const; // '--- friend class GFF4File; }; } // End of namespace Aurora #endif // AURORA_GFF4FILE_H xoreos-tools-0.0.5/src/aurora/herffile.cpp000066400000000000000000000111111331663051500205370ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * BioWare's HERF (hashed ERF) file parsing. */ #include #include "src/common/util.h" #include "src/common/error.h" #include "src/common/filepath.h" #include "src/common/memreadstream.h" #include "src/common/encoding.h" #include "src/common/hash.h" #include "src/aurora/herffile.h" #include "src/aurora/util.h" namespace Aurora { HERFFile::HERFFile(Common::SeekableReadStream *herf) : _herf(herf), _dictOffset(0xFFFFFFFF), _dictSize(0) { assert(_herf); load(*_herf); } HERFFile::~HERFFile() { } void HERFFile::load(Common::SeekableReadStream &herf) { uint32 magic = herf.readUint32LE(); if (magic != 0x00F1A5C0) throw Common::Exception("Invalid HERF file (0x%08X)", magic); uint32 resCount = herf.readUint32LE(); _resources.resize(resCount); _iResources.resize(resCount); try { searchDictionary(herf, resCount); readResList(herf); } catch (Common::Exception &e) { e.add("Failed reading HERF file"); throw; } } void HERFFile::searchDictionary(Common::SeekableReadStream &herf, uint32 resCount) { const uint32 dictHash = Common::hashStringDJB2("erf.dict"); const size_t pos = herf.pos(); for (uint32 i = 0; i < resCount; i++) { uint32 hash = herf.readUint32LE(); if (hash == dictHash) { _dictSize = herf.readUint32LE(); _dictOffset = herf.readUint32LE(); break; } herf.skip(8); } herf.seek(pos); } void HERFFile::readDictionary(Common::SeekableReadStream &herf, std::map &dict) { if (_dictOffset == 0xFFFFFFFF) return; size_t pos = herf.pos(); herf.seek(_dictOffset); uint32 magic = herf.readUint32LE(); if (magic != 0x00F1A5C0) throw Common::Exception("Invalid HERF dictionary (0x%08X)", magic); uint32 hashCount = herf.readUint32LE(); for (uint32 i = 0; i < hashCount; i++) { if ((size_t)herf.pos() >= (_dictOffset + _dictSize)) break; uint32 hash = herf.readUint32LE(); dict[hash] = Common::readStringFixed(herf, Common::kEncodingASCII, 128).toLower(); } herf.seek(pos); } void HERFFile::readResList(Common::SeekableReadStream &herf) { std::map dict; readDictionary(herf, dict); uint32 index = 0; ResourceList::iterator res = _resources.begin(); IResourceList::iterator iRes = _iResources.begin(); for (; (res != _resources.end()) && (iRes != _iResources.end()); ++index, ++res, ++iRes) { res->index = index; res->hash = herf.readUint32LE(); iRes->size = herf.readUint32LE(); iRes->offset = herf.readUint32LE(); if (iRes->offset >= (uint32)herf.size()) throw Common::Exception("HERFFile::readResList(): Resource goes beyond end of file"); std::map::const_iterator name = dict.find(res->hash); if (name != dict.end()) { res->name = Common::FilePath::getStem(name->second); res->type = TypeMan.getFileType(name->second); } if ((iRes->offset == _dictOffset) && (iRes->size == _dictSize)) { res->name = "erf"; res->type = kFileTypeDICT; } } } const Archive::ResourceList &HERFFile::getResources() const { return _resources; } const HERFFile::IResource &HERFFile::getIResource(uint32 index) const { if (index >= _iResources.size()) throw Common::Exception("Resource index out of range (%u/%u)", index, (uint)_iResources.size()); return _iResources[index]; } uint32 HERFFile::getResourceSize(uint32 index) const { return getIResource(index).size; } Common::SeekableReadStream *HERFFile::getResource(uint32 index, bool tryNoCopy) const { const IResource &res = getIResource(index); if (tryNoCopy) return new Common::SeekableSubReadStream(_herf.get(), res.offset, res.offset + res.size); _herf->seek(res.offset); return _herf->readStream(res.size); } Common::HashAlgo HERFFile::getNameHashAlgo() const { return Common::kHashDJB2; } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/herffile.h000066400000000000000000000062201331663051500202110ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * BioWare's HERF (hashed ERF) file parsing. */ #ifndef AURORA_HERFFILE_H #define AURORA_HERFFILE_H #include #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/ustring.h" #include "src/aurora/types.h" #include "src/aurora/archive.h" namespace Common { class SeekableReadStream; } namespace Aurora { /** Class to hold resource data of an HERF archive file. * * A HERF file is a very simplified version of a ERF file, similar to a * RIM file. But unlike a RIM file, a HERF file only stores djb2 hashes * of the included resource names. A dictionary, which matches hashes * back to names might be present, but doesn't have to. * * HERF files are only used in the Nintendo DS game Sonic Chronicles. */ class HERFFile : public Archive { public: /** Take over this stream and read an HERF file out of it. */ HERFFile(Common::SeekableReadStream *herf); ~HERFFile(); /** Return the list of resources. */ const ResourceList &getResources() const; /** Return the size of a resource. */ uint32 getResourceSize(uint32 index) const; /** Return a stream of the resource's contents. */ Common::SeekableReadStream *getResource(uint32 index, bool tryNoCopy = false) const; /** Return with which algorithm the name is hashed. */ Common::HashAlgo getNameHashAlgo() const; private: /** Internal resource information. */ struct IResource { uint32 offset; ///< The offset of the resource within the HERF. uint32 size; ///< The resource's size. }; typedef std::vector IResourceList; Common::ScopedPtr _herf; /** External list of resource names and types. */ ResourceList _resources; /** Internal list of resource offsets and sizes. */ IResourceList _iResources; uint32 _dictOffset; ///< The offset of the dict file (if available). uint32 _dictSize; ///< The size of the dict file (if available). void load(Common::SeekableReadStream &herf); void searchDictionary(Common::SeekableReadStream &herf, uint32 resCount); void readDictionary(Common::SeekableReadStream &herf, std::map &dict); void readResList(Common::SeekableReadStream &herf); void readNames(); const IResource &getIResource(uint32 index) const; }; } // End of namespace Aurora #endif // AURORA_HERFFILE_H xoreos-tools-0.0.5/src/aurora/keyfile.cpp000066400000000000000000000077621331663051500204240ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's KEYs (resource index files). */ /* See BioWare's own specs released for Neverwinter Nights modding * () */ #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/error.h" #include "src/common/readstream.h" #include "src/common/encoding.h" #include "src/aurora/keyfile.h" static const uint32 kKEYID = MKTAG('K', 'E', 'Y', ' '); static const uint32 kVersion1 = MKTAG('V', '1', ' ', ' '); static const uint32 kVersion11 = MKTAG('V', '1', '.', '1'); namespace Aurora { KEYFile::KEYFile(Common::SeekableReadStream &key) { load(key); } KEYFile::~KEYFile() { } void KEYFile::load(Common::SeekableReadStream &key) { readHeader(key); if (_id != kKEYID) throw Common::Exception("Not a KEY file (%s)", Common::debugTag(_id).c_str()); if ((_version != kVersion1) && (_version != kVersion11)) throw Common::Exception("Unsupported KEY file version %s", Common::debugTag(_version).c_str()); uint32 bifCount = key.readUint32LE(); uint32 resCount = key.readUint32LE(); _bifs.reserve(bifCount); _resources.reserve(resCount); // Version 1.1 has some NULL bytes here if (_version == kVersion11) key.skip(4); uint32 offFileTable = key.readUint32LE(); uint32 offResTable = key.readUint32LE(); key.skip( 8); // Build year and day key.skip(32); // Reserved try { _bifs.resize(bifCount); readBIFList(key, offFileTable); _resources.resize(resCount); readResList(key, offResTable); } catch (Common::Exception &e) { e.add("Failed reading KEY file"); throw; } } void KEYFile::readBIFList(Common::SeekableReadStream &key, uint32 offset) { key.seek(offset); for (BIFList::iterator bif = _bifs.begin(); bif != _bifs.end(); ++bif) { key.skip(4); // File size of the bif uint32 nameOffset = key.readUint32LE(); uint32 nameSize = 0; // nameSize is expanded to 4 bytes in 1.1 and the location is dropped if (_version == kVersion11) { nameSize = key.readUint32LE(); } else { nameSize = key.readUint16LE(); key.skip(2); // Location of the bif (HD, CD, ...) } const size_t curPos = key.seek(nameOffset); *bif = Common::readStringFixed(key, Common::kEncodingASCII, nameSize); key.seek(curPos); bif->replaceAll('\\', '/'); if (bif->beginsWith("/")) bif->erase(bif->begin()); } } void KEYFile::readResList(Common::SeekableReadStream &key, uint32 offset) { key.seek(offset); for (ResourceList::iterator res = _resources.begin(); res != _resources.end(); ++res) { res->name = Common::readStringFixed(key, Common::kEncodingASCII, 16); res->type = (FileType) key.readUint16LE(); uint32 id = key.readUint32LE(); // The new flags field holds the bifIndex now. The rest contains fixed // resource info. if (_version == kVersion11) { uint32 flags = key.readUint32LE(); res->bifIndex = (flags & 0xFFF00000) >> 20; } else res->bifIndex = id >> 20; // TODO: Fixed resources? res->resIndex = id & 0xFFFFF; } } const KEYFile::BIFList &KEYFile::getBIFs() const { return _bifs; } const KEYFile::ResourceList &KEYFile::getResources() const { return _resources; } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/keyfile.h000066400000000000000000000060731331663051500200630ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's KEYs (resource index files). */ #ifndef AURORA_KEYFILE_H #define AURORA_KEYFILE_H #include #include #include "src/common/types.h" #include "src/common/ustring.h" #include "src/aurora/types.h" #include "src/aurora/aurorafile.h" namespace Common { class SeekableReadStream; } namespace Aurora { /** Class to hold resource index information of a KEY file. * * A KEY file is one part of the KEY/BIF resource archive system. * The KEY file contains the resource names and types, and the BIF * file contains the actual resource data. So KEY files only contain * the resource meta-data. * * A KEY file can index resources of several BIF files and several * BIF files can in turn index different resources of the same BIF * file. * * See also class BIFFile in biffile.h. * * There are two versions of KEY files known and supported * - V1, used by Neverwinter Nights, Neverwinter Nights 2, Knight of * the Old Republic, Knight of the Old Republic II and Jade Empire * - V1.1, used by The Witcher * * Please note that KEY (and BIF) files found in Infinity Engine * games (Baldur's Gate et al) are not supported at all, even though * they claim to be V1. */ class KEYFile : boost::noncopyable, public AuroraFile { public: /** A key resource index. */ struct Resource { Common::UString name; ///< The resource's name. FileType type; ///< The resource's type. uint32 bifIndex; ///< Index into the bif list. uint32 resIndex; ///< Index into the bif's resource table. }; typedef std::vector ResourceList; typedef std::vector BIFList; KEYFile(Common::SeekableReadStream &key); ~KEYFile(); /** Return a list of all managed bifs. */ const BIFList &getBIFs() const; /** Return a list of all containing resources. */ const ResourceList &getResources() const; private: BIFList _bifs; ///< All managed bifs. ResourceList _resources; ///< All containing resources. void load(Common::SeekableReadStream &key); void readBIFList(Common::SeekableReadStream &key, uint32 offset); void readResList(Common::SeekableReadStream &key, uint32 offset); }; } // End of namespace Aurora #endif // AURORA_KEYFILE_H xoreos-tools-0.0.5/src/aurora/language.cpp000066400000000000000000000472371331663051500205600ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Types and functions related to language. */ #include #include "src/common/ustring.h" #include "src/common/memreadstream.h" #include "src/common/memwritestream.h" #include "src/aurora/language.h" #include "src/aurora/language_strings.h" DECLARE_SINGLETON(Aurora::LanguageManager) namespace Aurora { LanguageManager::LanguageManager() : _currentLanguageText(kLanguageInvalid), _currentLanguageVoice(kLanguageInvalid), _currentGender(kLanguageGenderMale), _fakeLanguage(1) { } LanguageManager::~LanguageManager() { } void LanguageManager::clear() { _langByID.clear(); _langByLang.clear(); _currentLanguageText = kLanguageInvalid; _currentLanguageVoice = kLanguageInvalid; _currentGender = kLanguageGenderMale; _fakeLanguage = 1; } void LanguageManager::addLanguage(Language language, uint32 id, Common::Encoding encoding) { Declaration declaration; declaration.language = language; declaration.id = id; declaration.encoding = encoding; declaration.encodingLocString = encoding; addLanguage(declaration); } void LanguageManager::addLanguage(Language language, uint32 id, Common::Encoding encoding, Common::Encoding encodingLocString) { Declaration declaration; declaration.language = language; declaration.id = id; declaration.encoding = encoding; declaration.encodingLocString = encodingLocString; addLanguage(declaration); } void LanguageManager::addLanguage(const Declaration &languageDeclaration) { if (languageDeclaration.id != kLanguageInvalid) _langByID[languageDeclaration.id] = languageDeclaration; if (languageDeclaration.language != kLanguageInvalid) _langByLang[languageDeclaration.language] = languageDeclaration; } void LanguageManager::addLanguages(const Declaration *languageDeclarations, size_t count) { while (count-- > 0) addLanguage(*languageDeclarations++); } static const LanguageManager::Declaration kLanguageDeclarations[kGameIDMAX][14] = { { { kLanguageEnglish , 0, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageFrench , 1, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageGerman , 2, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageItalian , 3, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageSpanish , 4, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguagePolish , 5, Common::kEncodingCP1250 , Common::kEncodingCP1250 }, { kLanguageKorean , 128, Common::kEncodingCP949 , Common::kEncodingCP949 }, { kLanguageChineseTraditional, 129, Common::kEncodingCP950 , Common::kEncodingCP950 }, { kLanguageChineseSimplified , 130, Common::kEncodingCP936 , Common::kEncodingCP936 }, { kLanguageJapanese , 131, Common::kEncodingCP932 , Common::kEncodingCP932 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } }, { { kLanguageEnglish , 0, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageFrench , 1, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageGerman , 2, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageItalian , 3, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageSpanish , 4, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguagePolish , 5, Common::kEncodingCP1250 , Common::kEncodingCP1250 }, { kLanguageKorean , 128, Common::kEncodingCP949 , Common::kEncodingCP949 }, { kLanguageChineseTraditional, 129, Common::kEncodingCP950 , Common::kEncodingCP950 }, { kLanguageChineseSimplified , 130, Common::kEncodingCP936 , Common::kEncodingCP936 }, { kLanguageJapanese , 131, Common::kEncodingCP932 , Common::kEncodingCP932 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } }, { { kLanguageEnglish , 0, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageFrench , 1, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageGerman , 2, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageItalian , 3, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageSpanish , 4, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguagePolish , 5, Common::kEncodingCP1250 , Common::kEncodingCP1250 }, { kLanguageKorean , 128, Common::kEncodingCP949 , Common::kEncodingCP949 }, { kLanguageChineseTraditional, 129, Common::kEncodingCP950 , Common::kEncodingCP950 }, { kLanguageChineseSimplified , 130, Common::kEncodingCP936 , Common::kEncodingCP936 }, { kLanguageJapanese , 131, Common::kEncodingCP932 , Common::kEncodingCP932 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } }, { { kLanguageEnglish , 0, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageFrench , 1, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageGerman , 2, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageItalian , 3, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageSpanish , 4, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguagePolish , 5, Common::kEncodingCP1250 , Common::kEncodingCP1250 }, { kLanguageKorean , 128, Common::kEncodingCP949 , Common::kEncodingCP949 }, { kLanguageChineseTraditional, 129, Common::kEncodingCP950 , Common::kEncodingCP950 }, { kLanguageChineseSimplified , 130, Common::kEncodingCP936 , Common::kEncodingCP936 }, { kLanguageJapanese , 131, Common::kEncodingCP932 , Common::kEncodingCP932 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } }, { { kLanguageEnglish , 0, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageFrench , 1, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageGerman , 2, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageItalian , 3, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageSpanish , 4, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguagePolish , 5, Common::kEncodingCP1250 , Common::kEncodingCP1250 }, { kLanguageKorean , 128, Common::kEncodingCP949 , Common::kEncodingCP949 }, { kLanguageChineseTraditional, 129, Common::kEncodingCP950 , Common::kEncodingCP950 }, { kLanguageChineseSimplified , 130, Common::kEncodingCP936 , Common::kEncodingCP936 }, { kLanguageJapanese , 131, Common::kEncodingCP932 , Common::kEncodingCP932 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } }, { { kLanguageDebug , 0, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageEnglish , 3, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguagePolish , 5, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageGerman , 10, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageFrench , 11, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageSpanish , 12, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageItalian , 13, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageRussian , 14, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageCzech , 15, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageHungarian , 16, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageKorean , 20, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageChineseTraditional, 21, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageChineseSimplified , 22, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } }, { { kLanguageEnglish , kLanguageInvalid, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageFrench , kLanguageInvalid, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageGerman , kLanguageInvalid, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageItalian , kLanguageInvalid, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageSpanish , kLanguageInvalid, Common::kEncodingCP1252 , Common::kEncodingCP1252 }, { kLanguageJapanese , kLanguageInvalid, Common::kEncodingUTF8 , Common::kEncodingUTF8 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } }, { { kLanguageEnglish , 0, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguageFrench , 1, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguageRussian , 2, Common::kEncodingUTF16LE, Common::kEncodingCP1251 }, { kLanguageItalian , 3, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguageGerman , 4, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguagePolish , 5, Common::kEncodingUTF16LE, Common::kEncodingCP1250 }, { kLanguageSpanish , 6, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguageCzech , 7, Common::kEncodingUTF16LE, Common::kEncodingCP1250 }, { kLanguageHungarian , 8, Common::kEncodingUTF16LE, Common::kEncodingCP1250 }, { kLanguageKorean , 9, Common::kEncodingUTF16LE, Common::kEncodingCP949 }, { kLanguageJapanese , 10, Common::kEncodingUTF16LE, Common::kEncodingCP932 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } }, { { kLanguageEnglish , 0, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguageFrench , 1, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguageRussian , 2, Common::kEncodingUTF16LE, Common::kEncodingCP1251 }, { kLanguageItalian , 3, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguageGerman , 4, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguagePolish , 5, Common::kEncodingUTF16LE, Common::kEncodingCP1250 }, { kLanguageSpanish , 6, Common::kEncodingUTF16LE, Common::kEncodingCP1252 }, { kLanguageCzech , 7, Common::kEncodingUTF16LE, Common::kEncodingCP1250 }, { kLanguageHungarian , 8, Common::kEncodingUTF16LE, Common::kEncodingCP1250 }, { kLanguageKorean , 9, Common::kEncodingUTF16LE, Common::kEncodingCP949 }, { kLanguageJapanese , 10, Common::kEncodingUTF16LE, Common::kEncodingCP932 }, { kLanguageInvalid , kLanguageInvalid, Common::kEncodingInvalid, Common::kEncodingInvalid } } }; void LanguageManager::declareLanguages(GameID game) { if ((uint) game >= kGameIDMAX) return; const Declaration *langs = kLanguageDeclarations[game]; while (langs->language != kLanguageInvalid) addLanguage(*langs++); } void LanguageManager::overrideEncoding(uint32 id, Common::Encoding encoding) { overrideEncoding(id, encoding, encoding); } void LanguageManager::overrideEncoding(uint32 id, Common::Encoding encoding, Common::Encoding encodingLocString) { Language language = kLanguageInvalid; // See if we already know this language ID. If so, override that entry const Declaration *decl = find(id); if (decl) language = decl->language; // Otherwise, conjure a fake language if (language == kLanguageInvalid) language = (Language) (((uint32) kLanguageMAX) + _fakeLanguage++); addLanguage(language, id, encoding, encodingLocString); } const LanguageManager::Declaration *LanguageManager::find(Language language) const { LanguageByLanguage::const_iterator l = _langByLang.find(language); if (l != _langByLang.end()) return &l->second; return 0; } const LanguageManager::Declaration *LanguageManager::find(uint32 id) const { LanguageByID::const_iterator l = _langByID.find(id); if (l != _langByID.end()) return &l->second; return 0; } uint32 LanguageManager::getLanguageID(Language language) const { const Declaration *l = find(language); if (!l) return kLanguageInvalid; return l->id; } uint32 LanguageManager::getLanguageID(Language language, LanguageGender gender) const { const Declaration *l = find(language); if (!l) return kLanguageInvalid; if (gender == kLanguageGenderCurrent) gender = getCurrentGender(); return convertLanguageIDToGendered(l->id, gender); } Language LanguageManager::getLanguage(uint32 languageID) const { const Declaration *l = find(languageID); if (!l) return kLanguageInvalid; return l->language; } Language LanguageManager::getLanguage(uint32 languageID, LanguageGender &gender) const { gender = getLanguageGender(languageID); const Declaration *l = find(convertLanguageIDToUngendered(languageID)); if (!l) return kLanguageInvalid; return l->language; } Language LanguageManager::getLanguageGendered(uint32 languageID) const { LanguageGender gender; return getLanguage(languageID, gender); } Common::Encoding LanguageManager::getEncoding(Language language) const { const Declaration *l = find(language); if (!l) return Common::kEncodingInvalid; return l->encoding; } Common::Encoding LanguageManager::getEncodingLocString(Language language) const { const Declaration *l = find(language); if (!l) return Common::kEncodingInvalid; return l->encodingLocString; } void LanguageManager::setCurrentLanguage(Language language) { setCurrentLanguageText(language); setCurrentLanguageVoice(language); } void LanguageManager::setCurrentLanguage(Language languageText, Language languageVoice) { setCurrentLanguageText(languageText); setCurrentLanguageVoice(languageVoice); } void LanguageManager::setCurrentGender(LanguageGender gender) { _currentGender = gender; } Language LanguageManager::getCurrentLanguageText() const { return _currentLanguageText; } Language LanguageManager::getCurrentLanguageVoice() const { return _currentLanguageVoice; } void LanguageManager::setCurrentLanguageText(Language language) { _currentLanguageText = language; } void LanguageManager::setCurrentLanguageVoice(Language language) { _currentLanguageVoice = language; } LanguageGender LanguageManager::getCurrentGender() const { return _currentGender; } Common::Encoding LanguageManager::getCurrentEncoding() const { return getEncoding(getCurrentLanguageText()); } Common::Encoding LanguageManager::getCurrentEncodingLocString() const { return getEncodingLocString(getCurrentLanguageText()); } uint32 LanguageManager::convertLanguageIDToGendered(uint32 languageID, LanguageGender gender) { assert(((size_t) gender) < kLanguageGenderMAX); if (languageID == kLanguageInvalid) return kLanguageInvalid; // In gendered language use, the ID is: // - ID * 2 + 0 for male // - ID * 2 + 1 for female return languageID * 2 + ((size_t) gender); } uint32 LanguageManager::convertLanguageIDToUngendered(uint32 languageID) { if (languageID == kLanguageInvalid) return kLanguageInvalid; return languageID / 2; } LanguageGender LanguageManager::getLanguageGender(uint32 languageID) { if (languageID == kLanguageInvalid) return kLanguageGenderMale; return (LanguageGender) (languageID % 2); } uint32 LanguageManager::swapLanguageGender(uint32 languageID) { if (languageID == kLanguageInvalid) return kLanguageInvalid; return languageID ^ 1; } Common::UString LanguageManager::getLanguageName(Language language) { if (language == kLanguageChinese) return "Chinese"; if (((uint32) language >= kLanguageMAX)) return "Invalid"; return kLanguageNames[language]; } Language LanguageManager::parseLanguage(const Common::UString &str) { if (str.empty()) return kLanguageInvalid; Common::UString lowerStr = str.toLower(); for (size_t i = 0; i < ARRAYSIZE(kLanguageStrings); i++) { for (size_t j = 0; j < ARRAYSIZE(kLanguageStrings[i].strings); j++) { if (!kLanguageStrings[i].strings[j]) break; if (lowerStr == kLanguageStrings[i].strings[j]) return kLanguageStrings[i].language; } } return kLanguageInvalid; } Common::MemoryReadStream *LanguageManager::preParseColorCodes(Common::SeekableReadStream &stream) { Common::MemoryWriteStreamDynamic output; output.reserve(stream.size()); int state = 0; std::vector collect; collect.reserve(6); byte color[3]; byte b; while (stream.read(&b, 1) == 1) { if (state == 0) { if (b == '<') { collect.push_back(b); state = 1; } else output.writeByte(b); continue; } if (state == 1) { if (b == 'c') { collect.push_back(b); state = 2; } else { output.write(&collect[0], collect.size()); output.writeByte(b); collect.clear(); state = 0; } continue; } if ((state == 2) || (state == 3) || (state == 4)) { collect.push_back(b); color[state - 2] = b; state++; continue; } if (state == 5) { if (b == '>') { Common::UString c = Common::UString::format("", (uint8) color[0], (uint8) color[1], (uint8) color[2], (uint8) 0xFF); output.writeString(c); collect.clear(); state = 0; } else { output.write(&collect[0], collect.size()); output.writeByte(b); collect.clear(); state = 0; } continue; } } return new Common::MemoryReadStream(output.getData(), output.size(), true); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/language.h000066400000000000000000000261021331663051500202110ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Types and functions related to language. */ #ifndef AURORA_LANGUAGE_H #define AURORA_LANGUAGE_H #include #include "src/common/types.h" #include "src/common/singleton.h" #include "src/common/encoding.h" #include "src/aurora/types.h" namespace Common { class UString; class SeekableReadStream; class MemoryReadStream; } namespace Aurora { enum Language { kLanguageEnglish, kLanguageFrench, kLanguageGerman, kLanguageItalian, kLanguageSpanish, kLanguagePolish, kLanguageCzech, kLanguageHungarian, kLanguageRussian, kLanguageKorean, kLanguageChineseTraditional, kLanguageChineseSimplified, kLanguageJapanese, kLanguageMAX, kLanguageDebug = 0xFFFFFFFD, ///< Pseudo value for debug strings. kLanguageChinese = 0xFFFFFFFE, ///< Pseudo value that means either traditional or simplified Chinese. kLanguageInvalid = 0xFFFFFFFF }; enum LanguageGender { kLanguageGenderMale = 0, kLanguageGenderFemale = 1, kLanguageGenderMAX, kLanguageGenderCurrent = 0xFF ///< Pseudo value that means the current language gender. }; /** The global language manager. * * The language manager holds all known supported languages of a game, as well * as the currently selected language(s) and gender (see below for details). * * A language consists of these parts: * - A value of the Language type, describing what exact language this is. * - A numerical language ID by which the language is referenced in game data * files. This is the ungendered version of the language ID (see below for * details). * - The encoding to use when reading or writing text strings of this language. * - The encoding to use when reading or writing LocStrings of this language. * This can, but does not have to, be the same encoding as other strings of * this language. * * Since the encoding can be different when reading LocStrings, two different * functions exist to query the encoding of language strings: one for * LocStrings and one for other string.s * * Depending on the game, two different languages might be selected at the * same time, differentiating between use: the current language for text and * the current language for speech. Therefore, there are also two functions to * query the current language: one for the current text language, one for the * current speech language. * * A language ID exists in two variants: gendered and ungendered. Some data * files specify ungendered language IDs, some gendered. A gendered language * ID is used to describe strings that may exist in two versions: one for * male player characters and one for female player characters. The ungendered * language ID used when describing a language as such. * * The ungendered language IDs of a game are usually a simple running index. * The gendered variant of an ungendered language ID x is 2 * x + 0 for male * and 2 * x + 1 for female. The LanguageManager has functions to convert * between gendered language IDs and ungendered language IDs plus Gender value. * * Likewise, the LanguageManager holds the value of the current gender of * the player character. */ class LanguageManager : public Common::Singleton { public: struct Declaration { Language language; uint32 id; Common::Encoding encoding; Common::Encoding encodingLocString; }; LanguageManager(); ~LanguageManager(); // .--- Managed language methods /** Clear all managed languages from the LanguageManager. */ void clear(); /** Add a supported language for the current game to the LanguageManager, * together with its internal (ungendered) language ID and usual encoding. */ void addLanguage(Language language, uint32 id, Common::Encoding encoding); /** Add a supported language for the current game to the LanguageManager, * together with its internal (ungendered) language ID, the usual encoding, * and the encoding when reading an embedded LocString string. */ void addLanguage(Language language, uint32 id, Common::Encoding encoding, Common::Encoding encodingLocString); /** Add a supported language for the current game to the LanguageManager, * together with its internal (ungendered) language ID and usual encoding. */ void addLanguage(const Declaration &languageDeclaration); /** Add several supported language for the current game to the LanguageManager, * together with their internal (ungendered) language ID and usual encoding. */ void addLanguages(const Declaration *languageDeclarations, size_t count); /** Add all supported languages for a specific game to the LanguageManager. */ void declareLanguages(GameID game); /** Override the encoding of a specific (ungendered) language ID. * * If this language ID has no language declared already, this method adds a * fake language entry! */ void overrideEncoding(uint32 id, Common::Encoding encoding); /** Override the encodings of a specific (ungendered) language ID. * * If this language ID has no language declared already, this method adds a * fake language entry! */ void overrideEncoding(uint32 id, Common::Encoding encoding, Common::Encoding encodingLocString); /** Construct the internal language ID for an ungendered use of a language. * * This is used by Aurora games in contexts where the gender of a player * character is not relevant, for example when querying or setting the * language the whole game runs. */ uint32 getLanguageID(Language language) const; /** Construct the internal language ID for an gendered use of a language. * * This is used by Aurora games in contexts where the gender of a player * character is relevant, for example when displaying dialogue strings * that might change depending on whether the player character is male * or female. */ uint32 getLanguageID(Language language, LanguageGender gender) const; /** Decode the internal language ID for an ungendered use of a language. * * See getLanguageID() on what constitutes gendered and ungendered * language use. */ Language getLanguage(uint32 languageID) const; /** Decode the internal language ID for a gendered use of a language. * * See getLanguageID() on what constitutes gendered and ungendered * language use. */ Language getLanguage(uint32 languageID, LanguageGender &gender) const; /** Decode the internal language ID for a gendered use of a language * (and ignore the language gender). * * See getLanguageID() on what constitutes gendered and ungendered * language use. */ Language getLanguageGendered(uint32 languageID) const; /** Return the encoding used for the given language. */ Common::Encoding getEncoding(Language language) const; /** Return the encoding used for the given language, for reading an embedded LocString string. */ Common::Encoding getEncodingLocString(Language language) const; // '--- // .--- Current language /** Change the current language, setting both text and voice to the same language. */ void setCurrentLanguage(Language language); /** Change the current language, separately for text and voice. */ void setCurrentLanguage(Language languageText, Language languageVoice); /** Change the current language, for text only. */ void setCurrentLanguageText(Language language); /** Change the current language, for voice only. */ void setCurrentLanguageVoice(Language language); /** Change the gender modulating the current language. */ void setCurrentGender(LanguageGender gender); /** Return the current language for text. */ Language getCurrentLanguageText() const; /** Return the current language for voices. */ Language getCurrentLanguageVoice() const; /** Return the gender modulating the current language. */ LanguageGender getCurrentGender() const; /** Return the encoding for the current text language. */ Common::Encoding getCurrentEncoding() const; /** Return the encoding for the current text language, for reading an embedded LocString string. */ Common::Encoding getCurrentEncodingLocString() const; // '--- // .--- Static language utility methods /** Return the human readable name of a language. */ static Common::UString getLanguageName(Language language); /** Parse this string into a language. */ static Language parseLanguage(const Common::UString &str); /** Convert an ungendered language ID to a gendered language ID. */ static uint32 convertLanguageIDToGendered(uint32 languageID, LanguageGender gender); /** Convert a gendered language ID to an ungendered language ID. */ static uint32 convertLanguageIDToUngendered(uint32 languageID); /** Return the gender of this gendered language ID. */ static LanguageGender getLanguageGender(uint32 languageID); /** Swap the gender of this gendered language ID. */ static uint32 swapLanguageGender(uint32 languageID); /** Pre-parse and fix color codes found in UI and dialogue strings in Aurora games. * * Aurora games (or Neverwinter Nights at least) allow for color codes of the * form "" (and closing with ""). The ??? are direct byte values taken * as red, green and blue values, breaking the usual text encoding. * * To fix that, we pre-parse those strings, converting "" into "", * where XXXXXX are the byte values in hexadecimal notation. * * Note that this function will only work for encodings where ASCII values are * directly encoded as ASCII. Namely, ASCII, Latin9, UTF-8, Windows CP-1250, * Windows CP-1252 and many of the variable-byte Windows codepages used for * Asian languages. This function will *not* work for UTF-16 and UTF-32. * * Also note that we're hoping that "" won't collide with valid characters * inside multibyte sequences. This is reasonable likely to never happen. */ static Common::MemoryReadStream *preParseColorCodes(Common::SeekableReadStream &stream); // '--- private: typedef std::map LanguageByID; typedef std::map LanguageByLanguage; LanguageByID _langByID; LanguageByLanguage _langByLang; Language _currentLanguageText; Language _currentLanguageVoice; LanguageGender _currentGender; uint32 _fakeLanguage; const Declaration *find(Language language) const; const Declaration *find(uint32 id) const; }; } // End of namespace Aurora /** Shortcut for accessing the language manager. */ #define LangMan ::Aurora::LanguageManager::instance() #endif // AURORA_LANGUAGE_H xoreos-tools-0.0.5/src/aurora/language_strings.h000066400000000000000000000122231331663051500217610ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Language <-> Language name mappings. */ #ifndef AURORA_LANGUAGE_STRINGS_H #define AURORA_LANGUAGE_STRINGS_H namespace Aurora { static const char * const kLanguageNames[] = { "English", "French", "German", "Italian", "Spanish", "Polish", "Czech", "Hungarian", "Russian", "Korean", "Traditional Chinese", "Simplified Chinese", "Japanese" }; struct LanguageStrings { Language language; const char *strings[32]; }; static const LanguageStrings kLanguageStrings[] = { { kLanguageEnglish, { "english", "british", "american", "e", "en", "eng", "en-us", "en_us", "en-uk", "en_uk", "en-usa", "en_usa", "en-gb", "en_gb", "en-gbr", "en_gbr", "eng-us", "eng_us", "eng-uk", "eng_uk", "eng-usa", "eng_usa", "eng-gb", "eng_gb", "eng-gbr", "eng_gbr", "us", "uk", "gbr", 0 } }, { kLanguageFrench, { "french", "francais", "fran\303\207ais", "franc\314\247ais", "france", "fr-fr", "fr_fr", "fra-fr", "fra_fr", "fre-fr", "fre_fr", "f", "fr", "fra", "fre", 0 } }, { kLanguageGerman, { "german", "germany", "deutsch", "deutschland", "de-de", "de_de", "de-at", "de_at", "de-ch", "de_ch", "deu-de", "deu_de", "deu-at", "deu_at", "deu-ch", "deu_ch", "ger-de", "ger_de", "ger-at", "ger_at", "ger-ch", "ger_ch", "d", "g", "de", "deu", "ger", 0 } }, { kLanguageItalian, { "italian", "italiano", "italy", "italia", "it-it", "it_it", "ita-it", "ita_it", "i", "it", "ita", 0 } }, { kLanguageSpanish, { "spanish", "espanol", "espa\303\221ol", "espan\314\203ol", "spain", "espana", "espa\303\221a", "espan\314\203ia", "es-es", "es_es", "esp-es", "esp_es", "s", "sp", "spa", "es", "esp", 0 } }, { kLanguagePolish, { "polish", "polski", "poland", "polska", "pl-pl", "pl_pl", "pol-pl", "pol_pl", "p", "pl", "pol", 0 } }, { kLanguageCzech, { "czech", "\304\215e\305\241tina", "c\314\214es\314\214tina", "ceska", "\304\215esk\303\201", "c\314\214eska\314\201", "cs-cz", "cs_cz", "cz-cz", "cz_cz", "ces-cz", "ces_cz", "cze-cz", "cze_cz", "cs", "cz", "ces", "cze", 0 } }, { kLanguageHungarian, { "hungarian", "magyar", "hungary", "magyar", "magyarorszag", "magyarorsz\303\201g", "magyarorsza\314\201g", "hu-hu", "hu_hu", "hun-hu", "hun_hu", "hu", "hun", 0 } }, { kLanguageRussian, { "russian", "russky", "russia", "rossiya", "\321\200\321\203\314\201\321\201\321\201\320\264\320\270\320\271", "\320\240\320\276\321\201\321\201\320\270\321\217", "\321\200\320\276\321\201\321\201\320\270\321\217", "ru-ru", "ru_ru", "rus-ru", "rus_ru", "ru", "rus", 0, } }, { kLanguageKorean, { "korean", "hangugeo", "chosonmal", "chos\305\217nmal", "choso\314\206nmal", "korea", "hanguk", "chosun", "ko-ko", "ko_ko", "kor-ko", "kor_ko", "ko-kp", "ko_kp", "ko-kr", "ko_kr", "kor-kp", "kor_kp", "kor-kr", "kor_kr", "ko", "kor", "kr", "kp", 0 } }, { kLanguageChineseTraditional, { "taiwan", "hongkong", "hong kong", "\350\207\272\347\201\243", "\345\217\260\347\201\243", "t\303\241iw\304\201n", "ta\314\201iwa\314\204n", "\351\246\231\346\270\257", "\344\270\255\345\234\213", "zh-cht", "zh_cht", "zho-cht", "zho_cht", "chi-cht", "chi_cht", "zh-hk", "zh_hk", "zho-hk", "zho_hk", "chi-hk", "chi_hk", "traditional", "traditional chinese", "traditionalchinese", "traditional-chinese", "traditional_chinese", 0 } }, { kLanguageChineseSimplified, { "china", "\344\270\255\345\233\275", "zhongguo", "zh\305\215nggu\303\263", "zho\314\204ngguo\314\201", "zh-chs", "zh_chs", "zho-chs", "zho_chs", "chi-chs", "chi_chs", "zh-cn", "zh_cn", "zho-cn", "zho_cn", "chi-cn", "chi_cn", "simplified", "simplified chinese", "simplifiedchinese", "simplified-chinese", "simplified_chinese", 0 } }, { kLanguageChinese, { "chinese", "mandarin", "putonghua", "guoyu", "\160\307\224\164\305\215\156\147\150\165\303\240", "\147\165\303\263\171\307\224", "\150\165\303\241\171\307\224", "\150\303\240\156\171\307\224", "zh", "zho", "chi", 0 } }, { kLanguageJapanese, { "japanese", "nihongo", "\346\227\245\346\234\254\350\252\236", "japan", "nihon", "nippon", "\346\227\245\346\234\254", "\346\227\245\346\234\254\345\233\275", "ja-ja", "ja_ja", "ja-jp", "ja_jp", "jpn-ja", "jpn_ja", "jpn-jp", "jpn_jp", "ja", "jp", "jpn", "jap", 0 } } }; } // End of namespace Aurora #endif // AURORA_LANGUAGE_STRINGS_H xoreos-tools-0.0.5/src/aurora/locstring.cpp000066400000000000000000000136721331663051500207750ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's localized strings. */ /* See BioWare's own specs released for Neverwinter Nights modding * () */ #include "src/common/util.h" #include "src/common/scopedptr.h" #include "src/common/memreadstream.h" #include "src/common/encoding.h" #include "src/aurora/locstring.h" #include "src/aurora/aurorafile.h" namespace Aurora { LocString::LocString() : _id(kStrRefInvalid) { } LocString::~LocString() { } void LocString::clear() { _id = kStrRefInvalid; _strings.clear(); } bool LocString::empty() const { return (_id == kStrRefInvalid) && (_strings.empty() || getString().empty()); } void LocString::swap(LocString &str) { SWAP(_id, str._id); _strings.swap(str._strings); } uint32 LocString::getNumStrings() const { return _strings.size(); } uint32 LocString::getID() const { return _id; } void LocString::setID(uint32 id) { _id = id; } bool LocString::hasString(Language language, LanguageGender gender) const { return hasString(LangMan.getLanguageID(language, gender)); } bool LocString::hasString(uint32 languageID) const { return _strings.find(languageID) != _strings.end(); } const Common::UString &LocString::getString(Language language, LanguageGender gender) const { return getString(LangMan.getLanguageID(language, gender)); } static const Common::UString kEmpty; const Common::UString &LocString::getString(uint32 languageID) const { StringMap::const_iterator s = _strings.find(languageID); if (s == _strings.end()) return kEmpty; return s->second; } void LocString::setString(Language language, LanguageGender gender, const Common::UString &str) { return setString(LangMan.getLanguageID(language, gender), str); } void LocString::setString(Language language, const Common::UString &str) { setString(language, kLanguageGenderMale , str); setString(language, kLanguageGenderFemale, str); } void LocString::setString(uint32 languageID, const Common::UString &str) { _strings[languageID] = str; } const Common::UString &LocString::getStrRefString() const { if (_id == kStrRefInvalid) return kEmpty; // TODO: Return numerical ID? return kEmpty; } const Common::UString &LocString::getFirstString() const { if (_strings.empty()) return getStrRefString(); return _strings.begin()->second; } const Common::UString &LocString::getString() const { uint32 languageID = LangMan.getLanguageID(LangMan.getCurrentLanguageText(), LangMan.getCurrentGender()); // Look whether we have an internal localized string if (hasString(languageID)) return getString(languageID); // Try the differently gendered internal string if (hasString(LangMan.swapLanguageGender(languageID))) return getString(LangMan.swapLanguageGender(languageID)); // Next, try the external localized one const Common::UString &refString = getStrRefString(); if (!refString.empty()) return refString; // If all else fails, just get the first one available return getFirstString(); } void LocString::getStrings(std::vector &str) const { for (StringMap::const_iterator s = _strings.begin(); s != _strings.end(); ++s) str.push_back(SubLocString(s->first, s->second)); } void LocString::readString(uint32 languageID, Common::SeekableReadStream &stream) { uint32 length = stream.readUint32LE(); std::pair s = _strings.insert(std::make_pair(languageID, "")); if (length == 0) return; s.first->second = "[???]"; Common::ScopedPtr data(stream.readStream(length)); Common::ScopedPtr parsed(LangMan.preParseColorCodes(*data)); Common::Encoding encoding = LangMan.getEncodingLocString(LangMan.getLanguageGendered(languageID)); if (encoding == Common::kEncodingInvalid) encoding = Common::kEncodingUTF8; try { s.first->second = Common::readString(*parsed, encoding); } catch (...) { parsed->seek(0); s.first->second = Common::readString(*parsed, Common::kEncodingCP1252); } } void LocString::readLocSubString(Common::SeekableReadStream &stream) { uint32 languageID = stream.readUint32LE(); readString(languageID, stream); } void LocString::readLocString(Common::SeekableReadStream &stream, uint32 id, uint32 count) { _id = id; while (count-- > 0) readLocSubString(stream); } void LocString::readLocString(Common::SeekableReadStream &stream) { uint32 id = stream.readUint32LE(); uint32 count = stream.readUint32LE(); readLocString(stream, id, count); } uint32 LocString::getWrittenSize(bool withNullTerminate) const { uint32 size = 0; for (StringMap::const_iterator iter = _strings.begin(); iter != _strings.end() ; iter++) { size += (*iter).second.size(); if (withNullTerminate) size += 1; size += 8; } return size; } void LocString::writeLocString(Common::WriteStream &stream, bool withNullTerminate) const { for (StringMap::const_iterator iter = _strings.begin(); iter != _strings.end() ; iter++) { stream.writeUint32LE((*iter).first); stream.writeUint32LE((*iter).second.size()); stream.write((*iter).second.c_str(), (*iter).second.size()); if (withNullTerminate) stream.writeByte(0); } } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/locstring.h000066400000000000000000000074421331663051500204400ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's localized strings. */ #ifndef AURORA_LOCSTRING_H #define AURORA_LOCSTRING_H #include #include #include "src/common/types.h" #include "src/common/ustring.h" #include "src/common/writestream.h" #include "src/aurora/language.h" namespace Common { class SeekableReadStream; } namespace Aurora { /** A localized string. */ class LocString { public: struct SubLocString { uint32 language; Common::UString str; SubLocString(uint32 l = 0, const Common::UString &s = "") : language(l), str(s) { } }; LocString(); ~LocString(); void clear(); /** Is this localized string empty, without any strings whatsoever? */ bool empty() const; /** Swap the contents of the LocString with this LocString's. */ void swap(LocString &str); /** Get the number of strings. */ uint32 getNumStrings() const; /** Return the string ID / StrRef. */ uint32 getID() const; /** Set the string ID / StrRef. */ void setID(uint32 id); /** Does the LocString have a string of this language? */ bool hasString(Language language, LanguageGender gender = kLanguageGenderCurrent) const; /** Get the string of that language. */ const Common::UString &getString(Language language, LanguageGender gender = kLanguageGenderCurrent) const; /** Set the string of that language. */ void setString(Language language, LanguageGender gender, const Common::UString &str); /** Set the string of that language (for all genders). */ void setString(Language language, const Common::UString &str); /** Get the string the StrRef points to. */ const Common::UString &getStrRefString() const; /** Get the first available string. */ const Common::UString &getFirstString() const; /** Try to get the most appropriate string. */ const Common::UString &getString() const; /** Return all strings. */ void getStrings(std::vector &str) const; /** Read a string out of a stream. */ void readString(uint32 languageID, Common::SeekableReadStream &stream); /** Read a LocSubString (substring of a LocString in game data) out of a stream. */ void readLocSubString(Common::SeekableReadStream &stream); /** Read a LocString out of a stream. */ void readLocString(Common::SeekableReadStream &stream, uint32 id, uint32 count); /** Read a LocString out of a stream. */ void readLocString(Common::SeekableReadStream &stream); /** Get the size, the string table will consume after being written. */ uint32 getWrittenSize(bool withNullTerminate = false) const; /** Write the LocString to a write stream. */ void writeLocString(Common::WriteStream &stream, bool withNullTerminate = false) const; private: typedef std::map StringMap; uint32 _id; ///< The string's ID / StrRef. StringMap _strings; bool hasString(uint32 languageID) const; const Common::UString &getString(uint32 languageID) const; void setString(uint32 languageID, const Common::UString &str); }; } // End of namespace Aurora #endif // AURORA_LOCSTRING_H xoreos-tools-0.0.5/src/aurora/ndsrom.cpp000066400000000000000000000111161331663051500202620ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Nintendo DS ROM parsing. */ // Based on http://dsibrew.org/wiki/NDS_Format #include #include "src/common/util.h" #include "src/common/ustring.h" #include "src/common/error.h" #include "src/common/memreadstream.h" #include "src/common/readfile.h" #include "src/common/encoding.h" #include "src/aurora/ndsrom.h" #include "src/aurora/util.h" namespace Aurora { NDSFile::NDSFile(const Common::UString &fileName) { _nds.reset(new Common::ReadFile(fileName)); load(*_nds); } NDSFile::NDSFile(Common::SeekableReadStream *nds) : _nds(nds) { assert(_nds); load(*_nds); } NDSFile::~NDSFile() { } void NDSFile::load(Common::SeekableReadStream &nds) { if (!isNDS(nds, _title, _code, _maker)) throw Common::Exception("Not a supported NDS ROM file"); nds.seek(0x40); uint32 fileNameTableOffset = nds.readUint32LE(); uint32 fileNameTableLength = nds.readUint32LE(); uint32 fatOffset = nds.readUint32LE(); //uint32 fatLength = nds.readUint32LE(); try { readNames(nds, fileNameTableOffset, fileNameTableLength); readFAT(nds, fatOffset); } catch (Common::Exception &e) { e.add("Failed reading NDS file"); throw; } } void NDSFile::readNames(Common::SeekableReadStream &nds, uint32 offset, uint32 length) { nds.seek(offset + 8); uint32 index = 0; while (((size_t)nds.pos()) < (size_t)(offset + length)) { Resource res; byte nameLength = nds.readByte(); if ((nameLength == 0) || ((size_t)nds.pos() >= (size_t)(offset + length))) break; Common::UString name = Common::readStringFixed(nds, Common::kEncodingASCII, nameLength).toLower(); res.name = TypeMan.setFileType(name, kFileTypeNone); res.type = TypeMan.getFileType(name); res.index = index++; _resources.push_back(res); } } void NDSFile::readFAT(Common::SeekableReadStream &nds, uint32 offset) { nds.seek(offset); _iResources.resize(_resources.size()); for (IResourceList::iterator res = _iResources.begin(); res != _iResources.end(); ++res) { res->offset = nds.readUint32LE(); res->size = nds.readUint32LE() - res->offset; // Value is the end offset } } const Common::UString &NDSFile::getTitle() const { return _title; } const Common::UString &NDSFile::getCode() const { return _code; } const Common::UString &NDSFile::getMaker() const { return _maker; } bool NDSFile::isNDS(Common::SeekableReadStream &stream, Common::UString &title, Common::UString &code, Common::UString &maker) { if (stream.size() < 0x40) return false; try { stream.seek(0); title = Common::readStringFixed(stream, Common::kEncodingASCII, 12); code = Common::readStringFixed(stream, Common::kEncodingASCII, 4); maker = Common::readStringFixed(stream, Common::kEncodingASCII, 2); } catch (...) { return false; } return true; } bool NDSFile::hasResource(Common::UString name) const { name.makeLower(); for (ResourceList::const_iterator r = _resources.begin(); r != _resources.end(); ++r) if (TypeMan.setFileType(r->name, r->type) == name) return true; return false; } const Archive::ResourceList &NDSFile::getResources() const { return _resources; } const NDSFile::IResource &NDSFile::getIResource(uint32 index) const { if (index >= _iResources.size()) throw Common::Exception("Resource index out of range (%u/%u)", index, (uint)_iResources.size()); return _iResources[index]; } uint32 NDSFile::getResourceSize(uint32 index) const { return getIResource(index).size; } Common::SeekableReadStream *NDSFile::getResource(uint32 index, bool tryNoCopy) const { const IResource &res = getIResource(index); _nds->seek(res.offset); if (tryNoCopy) return new Common::SeekableSubReadStream(_nds.get(), res.offset, res.offset + res.size); _nds->seek(res.offset); return _nds->readStream(res.size); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/ndsrom.h000066400000000000000000000064121331663051500177320ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Nintendo DS ROM parsing. */ #ifndef AURORA_NDSROM_H #define AURORA_NDSROM_H #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/ustring.h" #include "src/aurora/types.h" #include "src/aurora/archive.h" namespace Common { class UString; class SeekableReadStream; } namespace Aurora { /** A class encapsulating Nintendo DS ROM access. */ class NDSFile : public Archive { public: /** Over this file in the filesystem and read a NDS file out of it. */ NDSFile(const Common::UString &fileName); /** Take over this stream and read a NDS file out of it. */ NDSFile(Common::SeekableReadStream *nds); ~NDSFile(); /** Does the Nintendo DS ROM contain a certain resource? */ bool hasResource(Common::UString name) const; /** Return the list of resources. */ const ResourceList &getResources() const; /** Return the size of a resource. */ uint32 getResourceSize(uint32 index) const; /** Return a stream of the resource's contents. */ Common::SeekableReadStream *getResource(uint32 index, bool tryNoCopy = false) const; /** Return the game title string stored in the NDS header. */ const Common::UString &getTitle() const; /** Return the game code string stored in the NDS header. */ const Common::UString &getCode() const; /** Return the maker code string stored in the NDS header. */ const Common::UString &getMaker() const; /** Check if a stream is a valid Nintendo DS ROM and read its title, code and maker strings. */ static bool isNDS(Common::SeekableReadStream &stream, Common::UString &title, Common::UString &code, Common::UString &maker); private: /** Internal resource information. */ struct IResource { uint32 offset; ///< The offset of the resource within the NDS. uint32 size; ///< The resource's size. }; typedef std::vector IResourceList; Common::ScopedPtr _nds; Common::UString _title; Common::UString _code; Common::UString _maker; /** External list of resource names and types. */ ResourceList _resources; /** Internal list of resource offsets and sizes. */ IResourceList _iResources; void load(Common::SeekableReadStream &nds); void readNames(Common::SeekableReadStream &nds, uint32 offset, uint32 length); void readFAT(Common::SeekableReadStream &nds, uint32 offset); const IResource &getIResource(uint32 index) const; }; } // End of namespace Aurora #endif // AURORA_NDSROM_H xoreos-tools-0.0.5/src/aurora/nitrofile.cpp000066400000000000000000000047071331663051500207630ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Base class for Nitro (Nintendo DS) files. */ /* Most of the Nintendo DS file formats store a BOM signaling their endianness. * We interpret that BOM and return an appropriate SeekableSubReadStreamEndian. * * We have two ways of opening a Nitro file: * - The first takes a reference to a SeekableReadStream * - The second takes a pointer to a SeekableReadStream * The second one *always* takes over the original SeekableReadStream. */ #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/readstream.h" #include "src/aurora/nitrofile.h" namespace Aurora { static bool isBigEndian(Common::SeekableReadStream &stream) { stream.skip(4); // Tag, we don't care about that one here const uint16 bom = stream.readUint16BE(); if ((bom != 0xFFFE) && (bom != 0xFEFF)) throw Common::Exception("Invalid BOM: 0x%04X", (uint) bom); return bom == 0xFEFF; } Common::SeekableSubReadStreamEndian *NitroFile::open(Common::SeekableReadStream &stream) { const size_t begin = stream.pos(); const size_t end = stream.size(); const bool bigEndian = isBigEndian(stream); return new Common::SeekableSubReadStreamEndian(&stream, begin, end, bigEndian, false); } Common::SeekableSubReadStreamEndian *NitroFile::open(Common::SeekableReadStream *stream) { Common::ScopedPtr nitroStream(stream); const size_t begin = nitroStream->pos(); const size_t end = nitroStream->size(); const bool bigEndian = isBigEndian(*nitroStream); return new Common::SeekableSubReadStreamEndian(nitroStream.release(), begin, end, bigEndian, true); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/nitrofile.h000066400000000000000000000030171331663051500204210ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Base class for Nitro (Nintendo DS) files. */ #ifndef AURORA_NITROFILE_H #define AURORA_NITROFILE_H namespace Common { class SeekableReadStream; class SeekableSubReadStreamEndian; } namespace Aurora { class NitroFile { protected: /** Treat this stream as a Nitro file and return an endian'd stream according to its BOM. */ static Common::SeekableSubReadStreamEndian *open(Common::SeekableReadStream &stream); /** Treat this stream as a Nitro file, take it over and return an endian'd stream according to its BOM. */ static Common::SeekableSubReadStreamEndian *open(Common::SeekableReadStream *stream); }; } // End of namespace Aurora #endif // AURORA_NITROFILE_H xoreos-tools-0.0.5/src/aurora/nsbtxfile.cpp000066400000000000000000000355111331663051500207630ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Treat Nintendo NSBTX files, which contain multiple textures as an * archive of intermediate textures. */ /* Based heavily on the BTX0 reader found in the NDS file viewer * and editor Tinke by pleoNeX (), * which is licensed under the terms of the GPLv3. * * Tinke in turn is based on the NSBTX documentation by lowlines * () and the * Nintendo DS technical information GBATEK by Martin Korth * (). * * The original copyright note in Tinke reads as follows: * * Copyright (C) 2011 pleoNeX * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/error.h" #include "src/common/memreadstream.h" #include "src/common/memwritestream.h" #include "src/common/encoding.h" #include "src/aurora/nsbtxfile.h" static const uint32 kXEOSID = MKTAG('X', 'E', 'O', 'S'); static const uint32 kITEXID = MKTAG('I', 'T', 'E', 'X'); static const uint32 kXEOSITEXHeaderSize = 4 + 4 + 4 + 4 + 4 + 1 + 1 + 1 + 1 + 1 + 1; static const uint32 kXEOSITEXMipMapHeaderSize = 4 + 4 + 4; static const uint32 kBTX0ID = MKTAG('B', 'T', 'X', '0'); static const uint32 kTEX0ID = MKTAG('T', 'E', 'X', '0'); namespace Aurora { NSBTXFile::ReadContext::ReadContext(Common::SeekableSubReadStreamEndian &n, const Texture &t, Common::WriteStream &s) : texture(&t), nsbtx(&n), stream(&s) { } NSBTXFile::ReadContext::~ReadContext() { } NSBTXFile::NSBTXFile(Common::SeekableReadStream *nsbtx) { assert(nsbtx); _nsbtx.reset(open(nsbtx)); load(*_nsbtx); } NSBTXFile::~NSBTXFile() { } const Archive::ResourceList &NSBTXFile::getResources() const { return _resources; } uint32 NSBTXFile::getITEXSize(const Texture &texture) { return kXEOSITEXHeaderSize + kXEOSITEXMipMapHeaderSize + texture.width * texture.height * 4; } uint32 NSBTXFile::getResourceSize(uint32 index) const { if (index >= _textures.size()) throw Common::Exception("Texture index out of range (%u/%u)", index, (uint)_textures.size()); return getITEXSize(_textures[index]); } void NSBTXFile::writeITEXHeader(const ReadContext &ctx) { ctx.stream->writeUint32BE(kXEOSID); ctx.stream->writeUint32BE(kITEXID); ctx.stream->writeUint32LE(0); // Version ctx.stream->writeUint32LE(4); // Pixel format / bytes per pixel ctx.stream->writeByte((uint8) ctx.texture->wrapX); ctx.stream->writeByte((uint8) ctx.texture->wrapY); ctx.stream->writeByte((uint8) ctx.texture->flipX); ctx.stream->writeByte((uint8) ctx.texture->flipY); ctx.stream->writeByte((uint8) ctx.texture->coordTransform); ctx.stream->writeByte(0x00); // Don't filter the texture ctx.stream->writeUint32LE(1); // Number of mip maps ctx.stream->writeUint32LE(ctx.texture->width); ctx.stream->writeUint32LE(ctx.texture->height); ctx.stream->writeUint32LE(ctx.texture->width * ctx.texture->height * 4); } void NSBTXFile::writePixel(const ReadContext &ctx, byte r, byte g, byte b, byte a) { ctx.stream->writeByte(b); ctx.stream->writeByte(g); ctx.stream->writeByte(r); ctx.stream->writeByte(a); } void NSBTXFile::getTexture2bpp(const ReadContext &ctx) { for (uint32 y = 0; y < ctx.texture->height; y++) { for (uint32 x = 0; x < ctx.texture->width; ) { uint8 pixels = ctx.nsbtx->readByte(); for (uint32 n = 0; n < 4; n++, x++, pixels >>= 2) { const uint8 pixel = pixels & 3; const byte r = ctx.palette[pixel * 3 + 0]; const byte g = ctx.palette[pixel * 3 + 1]; const byte b = ctx.palette[pixel * 3 + 2]; const byte a = (ctx.texture->alpha && (pixel == 0)) ? 0x00 : 0xFF; writePixel(ctx, r, g, b, a); } } } } void NSBTXFile::getTexture4bpp(const ReadContext &ctx) { for (uint32 y = 0; y < ctx.texture->height; y++) { for (uint32 x = 0; x < ctx.texture->width; ) { uint8 pixels = ctx.nsbtx->readByte(); for (uint32 n = 0; n < 2; n++, x++, pixels >>= 4) { const uint8 pixel = pixels & 0xF; const byte r = ctx.palette[pixel * 3 + 0]; const byte g = ctx.palette[pixel * 3 + 1]; const byte b = ctx.palette[pixel * 3 + 2]; const byte a = (ctx.texture->alpha && (pixel == 0)) ? 0x00 : 0xFF; writePixel(ctx, r, g, b, a); } } } } void NSBTXFile::getTexture8bpp(const ReadContext &ctx) { for (uint32 y = 0; y < ctx.texture->height; y++) { for (uint32 x = 0; x < ctx.texture->width; x++) { const uint8 pixel = ctx.nsbtx->readByte(); const byte r = ctx.palette[pixel * 3 + 0]; const byte g = ctx.palette[pixel * 3 + 1]; const byte b = ctx.palette[pixel * 3 + 2]; const byte a = (ctx.texture->alpha && (pixel == 0)) ? 0x00 : 0xFF; writePixel(ctx, r, g, b, a); } } } void NSBTXFile::getTexture16bpp(const ReadContext &ctx) { for (uint32 y = 0; y < ctx.texture->height; y++) { for (uint32 x = 0; x < ctx.texture->width; x++) { const uint16 pixel = ctx.nsbtx->readUint16(); const byte r = ( pixel & 0x1F) << 3; const byte g = ((pixel >> 5) & 0x1F) << 3; const byte b = ((pixel >> 10) & 0x1F) << 3; const byte a = ((pixel >> 15) == 0) ? 0x00 : 0xFF; writePixel(ctx, r, g, b, a); } } } void NSBTXFile::getTextureA3I5(const ReadContext &ctx) { for (uint32 y = 0; y < ctx.texture->height; y++) { for (uint32 x = 0; x < ctx.texture->width; x++) { const uint8 pixel = ctx.nsbtx->readByte(); const uint8 index = pixel & 0x1F; const byte r = ctx.palette[index * 3 + 0]; const byte g = ctx.palette[index * 3 + 1]; const byte b = ctx.palette[index * 3 + 2]; const byte a = (((pixel >> 5) << 2) + (pixel >> 6)) << 3; writePixel(ctx, r, g, b, a); } } } void NSBTXFile::getTextureA5I3(const ReadContext &ctx) { for (uint32 y = 0; y < ctx.texture->height; y++) { for (uint32 x = 0; x < ctx.texture->width; x++) { const uint8 pixel = ctx.nsbtx->readByte(); const uint8 index = pixel & 0x07; const byte r = ctx.palette[index * 3 + 0]; const byte g = ctx.palette[index * 3 + 1]; const byte b = ctx.palette[index * 3 + 2]; const byte a = (pixel >> 3) << 3; writePixel(ctx, r, g, b, a); } } } const NSBTXFile::Palette *NSBTXFile::findPalette(const Texture &texture) const { std::vector palNames; palNames.push_back(texture.name); palNames.push_back(texture.name + "_pl"); palNames.push_back(texture.name + "_p"); palNames.push_back(texture.name + "_"); for (std::vector::iterator n = palNames.begin(); n != palNames.end(); ++n) for (Palettes::const_iterator p = _palettes.begin(); p != _palettes.end(); ++p) if (p->name == *n) return &*p; return 0; } void NSBTXFile::getPalette(ReadContext &ctx) const { static const uint16 kPaletteSize[] = { 0, 32, 4, 16, 256, 256, 8, 0 }; const uint16 size = kPaletteSize[(size_t)ctx.texture->format] * 3; if (size == 0) return; const Palette *palette = findPalette(*ctx.texture); if (!palette) throw Common::Exception("Couldn't find a palette for texture \"%s\"", ctx.texture->name.c_str()); Common::ScopedArray palData(new byte[size]); memset(palData.get(), 0, size); ctx.nsbtx->seek(palette->offset); const uint16 palDataSize = MIN(size, ((ctx.nsbtx->size() - ctx.nsbtx->pos()) / 2) * 3); for (uint16 i = 0; i < palDataSize; i += 3) { const uint16 pixel = ctx.nsbtx->readUint16(); palData[i + 0] = ( pixel & 0x1F) << 3; palData[i + 1] = ((pixel >> 5) & 0x1F) << 3; palData[i + 2] = ((pixel >> 10) & 0x1F) << 3; } ctx.palette.reset(palData.release()); } void NSBTXFile::getTexture(const ReadContext &ctx) { ctx.nsbtx->seek(ctx.texture->offset); switch (ctx.texture->format) { case kFormat2bpp: getTexture2bpp(ctx); break; case kFormat4bpp: getTexture4bpp(ctx); break; case kFormat8bpp: getTexture8bpp(ctx); break; case kFormat16bpp: getTexture16bpp(ctx); break; case kFormatA3I5: getTextureA3I5(ctx); break; case kFormatA5I3: getTextureA5I3(ctx); break; default: throw Common::Exception("Unsupported texture format %d", (int) ctx.texture->format); break; } } Common::SeekableReadStream *NSBTXFile::getResource(uint32 index, bool UNUSED(tryNoCopy)) const { if (index >= _textures.size()) throw Common::Exception("Texture index out of range (%u/%u)", index, (uint)_textures.size()); Common::MemoryWriteStreamDynamic stream(true, getITEXSize(_textures[index])); ReadContext ctx(*_nsbtx, _textures[index], stream); writeITEXHeader(ctx); getPalette(ctx); getTexture(ctx); stream.setDisposable(false); return new Common::MemoryReadStream(stream.getData(), stream.size(), true); } void NSBTXFile::load(Common::SeekableSubReadStreamEndian &nsbtx) { try { readHeader(nsbtx); readTextures(nsbtx); readPalettes(nsbtx); createResourceList(); } catch (Common::Exception &e) { e.add("Failed reading NSBTX file"); throw; } } void NSBTXFile::readHeader(Common::SeekableSubReadStreamEndian &nsbtx) { readFileHeader(nsbtx); readInfoHeader(nsbtx); } void NSBTXFile::readFileHeader(Common::SeekableSubReadStreamEndian &nsbtx) { const uint32 tag = nsbtx.readUint32BE(); if (tag != kBTX0ID) throw Common::Exception("Invalid NSBTX file (%s)", Common::debugTag(tag).c_str()); const uint16 bom = nsbtx.readUint16(); if (bom != 0xFEFF) throw Common::Exception("Invalid BOM: 0x%04X", (uint) bom); const uint8 versionMajor = nsbtx.readByte(); const uint8 versionMinor = nsbtx.readByte(); if ((versionMajor != 1) || (versionMinor != 0)) throw Common::Exception("Unsupported version %u.%u", versionMajor, versionMinor); const uint32 fileSize = nsbtx.readUint32(); if (fileSize > (uint32)nsbtx.size()) throw Common::Exception("Size too large (%u > %u)", fileSize, (uint)nsbtx.size()); const uint16 headerSize = nsbtx.readUint16(); if (headerSize != 16) throw Common::Exception("Invalid header size (%u)", headerSize); const uint16 sectionCount = nsbtx.readUint16(); if (sectionCount != 1) throw Common::Exception("Invalid number of sections (%u)", sectionCount); _textureOffset = nsbtx.readUint32(); } void NSBTXFile::readInfoHeader(Common::SeekableSubReadStreamEndian &nsbtx) { nsbtx.seek(_textureOffset); const uint32 tag = nsbtx.readUint32BE(); if (tag != kTEX0ID) throw Common::Exception("Invalid NSBTX texture (%s)", Common::debugTag(tag).c_str()); nsbtx.skip(4 + 4 + 2); // Section size + padding + data size _textureInfoOffset = _textureOffset + nsbtx.readUint16(); nsbtx.skip(4); // Padding _textureDataOffset = _textureOffset + nsbtx.readUint32(); nsbtx.skip(4); // Padding nsbtx.skip(2 + 2); // Compressed data size and info offset nsbtx.skip(4); // Padding nsbtx.skip(4 + 4); // Compressed data offset and info data offset nsbtx.skip(4); // Padding nsbtx.skip(4); // Palette data size _paletteInfoOffset = _textureOffset + nsbtx.readUint32(); _paletteDataOffset = _textureOffset + nsbtx.readUint32(); } void NSBTXFile::readTextures(Common::SeekableSubReadStreamEndian &nsbtx) { nsbtx.seek(_textureInfoOffset); nsbtx.skip(1); // Unknown const uint8 textureCount = nsbtx.readByte(); nsbtx.skip(2); // Section size nsbtx.skip(2 + 2 + 4 + textureCount * (2 + 2)); // Unknown nsbtx.skip(2 + 2); // Header size + section size _textures.resize(textureCount); for (Textures::iterator t = _textures.begin(); t != _textures.end(); ++t) { t->offset = _textureDataOffset + nsbtx.readUint16() * 8; const uint16 flags = nsbtx.readUint16(); nsbtx.skip(1); // Unknown const uint8 unknown = nsbtx.readByte(); nsbtx.skip(2); // Unknown t->width = 8 << ((flags >> 4) & 7); t->height = 8 << ((flags >> 7) & 7); t->format = (Format) ((flags >> 10) & 7); t->wrapX = ( flags & 1) != 0; t->wrapY = ((flags >> 1) & 1) != 0; t->flipX = ((flags >> 2) & 1) != 0; t->flipY = ((flags >> 3) & 1) != 0; t->alpha = ((flags >> 13) & 1) != 0; t->coordTransform = (Transform) (flags >> 14); if (t->width == 0x00) { switch (unknown & 0x3) { case 2: t->width = 0x200; break; default: t->width = 0x100; break; } } if (t->height == 0x00) { switch ((unknown >> 4) & 0x3) { case 2: t->height = 0x200; break; default: t->height = 0x100; break; } } } for (Textures::iterator t = _textures.begin(); t != _textures.end(); ++t) t->name = Common::readStringFixed(nsbtx, Common::kEncodingASCII, 16).toLower(); } void NSBTXFile::readPalettes(Common::SeekableSubReadStreamEndian &nsbtx) { nsbtx.seek(_paletteInfoOffset); nsbtx.skip(1); // Unknown const uint8 paletteCount = nsbtx.readByte(); nsbtx.skip(2); // Section size nsbtx.skip(2 + 2 + 4 + paletteCount * (2 + 2)); // Unknown nsbtx.skip(2 + 2); // Header size + section size _palettes.resize(paletteCount); for (Palettes::iterator p = _palettes.begin(); p != _palettes.end(); ++p) { const uint16 offset = nsbtx.readUint16() & 0x1FFF; const uint16 flags = nsbtx.readUint16(); const uint8 paletteStep = ((flags & 1) != 0) ? 16 : 8; p->offset = _paletteDataOffset + offset * paletteStep; } for (Palettes::iterator p = _palettes.begin(); p != _palettes.end(); ++p) p->name = Common::readStringFixed(nsbtx, Common::kEncodingASCII, 16).toLower(); } void NSBTXFile::createResourceList() { _resources.resize(_textures.size()); ResourceList::iterator res = _resources.begin(); Textures::iterator tex = _textures.begin(); uint32 index = 0; for ( ; (res != _resources.end()) && (tex != _textures.end()); ++res, ++tex, ++index) { res->name = tex->name; res->type = kFileTypeXEOSITEX; res->index = index; } } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/nsbtxfile.h000066400000000000000000000115311331663051500204240ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Treat Nintendo NSBTX files, which contain multiple textures as an * archive of intermediate textures. */ #ifndef AURORA_NSBTXFILE_H #define AURORA_NSBTXFILE_H #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/ustring.h" #include "src/aurora/types.h" #include "src/aurora/archive.h" #include "src/aurora/nitrofile.h" namespace Common { class WriteStream; } namespace Aurora { class NSBTXFile : public Archive, public NitroFile { public: /** Take over this stream and read an NSBTX file out of it. */ NSBTXFile(Common::SeekableReadStream *nsbtx); ~NSBTXFile(); /** Return the list of resources. */ const ResourceList &getResources() const; /** Return the size of a resource. */ uint32 getResourceSize(uint32 index) const; /** Return a stream of the resource's contents. */ Common::SeekableReadStream *getResource(uint32 index, bool tryNoCopy = false) const; private: enum Format { kFormatNoTexture = 0, ///< Empty. kFormatA3I5 = 1, ///< 3bit alpha + 5bit color index. kFormat2bpp = 2, ///< 2bit color index. kFormat4bpp = 3, ///< 4bit color index. kFormat8bpp = 4, ///< 8bit color index. kFormat4x4Compressed = 5, ///< 32bit per 4x4 texel block (Unsupported). kFormatA5I3 = 6, ///< 5bit alpha + 3bit color index. kFormat16bpp = 7 ///< R5B5G5A1. }; enum Transform { kTransformNone = 0, ///< No extra texture coordinate transform. kTransformTexCoord = 1, ///< Transform texture coordinates using TexCoords. kTransformNormal = 2, ///< Transform texture coordinates using Normals. kTransformVertex = 3 ///< Transform texture coordinates using Vertices. }; struct Texture { Common::UString name; uint32 offset; Format format; uint16 width; uint16 height; bool wrapX; ///< true: wrap, false: clamp. bool wrapY; ///< true: wrap, false: clamp. bool flipX; ///< true: flip on every 2nd texture wrap. bool flipY; ///< true: flip on every 2nd texture wrap. bool alpha; ///< true: color index 0 is transparent. Transform coordTransform; }; struct Palette { Common::UString name; uint32 offset; }; struct ReadContext { const Texture *texture; Common::ScopedArray palette; Common::SeekableSubReadStreamEndian *nsbtx; Common::WriteStream *stream; ReadContext(Common::SeekableSubReadStreamEndian &n, const Texture &t, Common::WriteStream &s); ~ReadContext(); }; typedef std::vector Textures; typedef std::vector Palettes; /** The name of the NSBTX file. */ Common::ScopedPtr _nsbtx; /** External list of resource names and types. */ ResourceList _resources; uint32 _textureOffset; uint32 _textureInfoOffset; uint32 _paletteInfoOffset; uint32 _textureDataOffset; uint32 _paletteDataOffset; Textures _textures; Palettes _palettes; void load(Common::SeekableSubReadStreamEndian &nsbtx); void readHeader (Common::SeekableSubReadStreamEndian &nsbtx); void readFileHeader(Common::SeekableSubReadStreamEndian &nsbtx); void readInfoHeader(Common::SeekableSubReadStreamEndian &nsbtx); void readTextures (Common::SeekableSubReadStreamEndian &nsbtx); void readPalettes (Common::SeekableSubReadStreamEndian &nsbtx); void createResourceList(); const Palette *findPalette(const Texture &texture) const; void getPalette(ReadContext &ctx) const; static uint32 getITEXSize(const Texture &texture); static void writeITEXHeader(const ReadContext &ctx); static void writePixel(const ReadContext &ctx, byte r, byte g, byte b, byte a); static void getTexture (const ReadContext &ctx); static void getTexture2bpp (const ReadContext &ctx); static void getTexture4bpp (const ReadContext &ctx); static void getTexture8bpp (const ReadContext &ctx); static void getTexture16bpp(const ReadContext &ctx); static void getTextureA3I5 (const ReadContext &ctx); static void getTextureA5I3 (const ReadContext &ctx); }; } // End of namespace Aurora #endif // AURORA_NSBTXFILE_H xoreos-tools-0.0.5/src/aurora/rimfile.cpp000066400000000000000000000065761331663051500204250ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's RIMs (resource archives). */ #include #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/memreadstream.h" #include "src/common/error.h" #include "src/common/encoding.h" #include "src/aurora/rimfile.h" static const uint32 kRIMID = MKTAG('R', 'I', 'M', ' '); static const uint32 kVersion1 = MKTAG('V', '1', '.', '0'); namespace Aurora { RIMFile::RIMFile(Common::SeekableReadStream *rim) : _rim(rim) { assert(_rim); load(*_rim); } RIMFile::~RIMFile() { } void RIMFile::load(Common::SeekableReadStream &rim) { readHeader(rim); if (_id != kRIMID) throw Common::Exception("Not a RIM file (%s)", Common::debugTag(_id).c_str()); if (_version != kVersion1) throw Common::Exception("Unsupported RIM file version %s", Common::debugTag(_version).c_str()); rim.skip(4); // Reserved uint32 resCount = rim.readUint32LE(); // Number of resources in the RIM uint32 offResList = rim.readUint32LE(); // Offset to the resource list _resources.resize(resCount); _iResources.resize(resCount); try { // Read the resource list readResList(rim, offResList); } catch (Common::Exception &e) { e.add("Failed reading RIM file"); throw; } } void RIMFile::readResList(Common::SeekableReadStream &rim, uint32 offset) { rim.seek(offset); uint32 index = 0; ResourceList::iterator res = _resources.begin(); IResourceList::iterator iRes = _iResources.begin(); for (; (res != _resources.end()) && (iRes != _iResources.end()); ++index, ++res, ++iRes) { res->name = Common::readStringFixed(rim, Common::kEncodingASCII, 16); res->type = (FileType) rim.readUint16LE(); res->index = index; rim.skip(4 + 2); // Resource ID + Reserved iRes->offset = rim.readUint32LE(); iRes->size = rim.readUint32LE(); } } const Archive::ResourceList &RIMFile::getResources() const { return _resources; } const RIMFile::IResource &RIMFile::getIResource(uint32 index) const { if (index >= _iResources.size()) throw Common::Exception("Resource index out of range (%u/%u)", index, (uint)_iResources.size()); return _iResources[index]; } uint32 RIMFile::getResourceSize(uint32 index) const { return getIResource(index).size; } Common::SeekableReadStream *RIMFile::getResource(uint32 index, bool tryNoCopy) const { const IResource &res = getIResource(index); if (tryNoCopy) return new Common::SeekableSubReadStream(_rim.get(), res.offset, res.offset + res.size); _rim->seek(res.offset); return _rim->readStream(res.size); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/rimfile.h000066400000000000000000000062551331663051500200640ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's RIMs (resource archives). */ #ifndef AURORA_RIMFILE_H #define AURORA_RIMFILE_H #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/aurora/types.h" #include "src/aurora/archive.h" #include "src/aurora/aurorafile.h" namespace Common { class SeekableReadStream; } namespace Aurora { /** Class to hold resource data of a RIM archive file. * * A RIM file is a resource archive, used in several Aurora games. * It is a simplified version of the more complex ERF format, lacking * the support for a localized description text as found in early ERF * formats, as well as compression and encryption as found in later * ERF formats. * * There is only one single version, V1.0, of the RIM format known and * supported. For each resource file, it stores a path- and extension-less * name (with a maximum of 16 ASCII characters) and a Type ID. * * RIM files are found in Knights of the Old Republic, Knights of the Old * Republic II and Jade Empire. They always have the .rim extension. * * Note: .rim files in the Dragon Age games are not real RIM files. * Instead, they are ERF files. See class ERFFile in erffile.h. */ class RIMFile : public Archive, public AuroraFile { public: /** Take over this stream and read a RIM file out of it. */ RIMFile(Common::SeekableReadStream *rim); ~RIMFile(); /** Return the list of resources. */ const ResourceList &getResources() const; /** Return the size of a resource. */ uint32 getResourceSize(uint32 index) const; /** Return a stream of the resource's contents. */ Common::SeekableReadStream *getResource(uint32 index, bool tryNoCopy = false) const; private: /** Internal resource information. */ struct IResource { uint32 offset; ///< The offset of the resource within the RIM. uint32 size; ///< The resource's size. }; typedef std::vector IResourceList; Common::ScopedPtr _rim; /** External list of resource names and types. */ ResourceList _resources; /** Internal list of resource offsets and sizes. */ IResourceList _iResources; void load(Common::SeekableReadStream &rim); void readResList(Common::SeekableReadStream &rim, uint32 offset); const IResource &getIResource(uint32 index) const; }; } // End of namespace Aurora #endif // AURORA_RIMFILE_H xoreos-tools-0.0.5/src/aurora/rules.mk000066400000000000000000000050061331663051500177400ustar00rootroot00000000000000# xoreos-tools - Tools to help with xoreos development # # xoreos-tools is the legal property of its developers, whose names # can be found in the AUTHORS file distributed with this source # distribution. # # xoreos-tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # xoreos-tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with xoreos-tools. If not, see . # Aurora file loaders and related support code. noinst_LTLIBRARIES += src/aurora/libaurora.la src_aurora_libaurora_la_SOURCES = src_aurora_libaurora_la_SOURCES += \ src/aurora/types.h \ src/aurora/util.h \ src/aurora/language.h \ src/aurora/language_strings.h \ src/aurora/archive.h \ src/aurora/aurorafile.h \ src/aurora/erffile.h \ src/aurora/rimfile.h \ src/aurora/keyfile.h \ src/aurora/biffile.h \ src/aurora/ndsrom.h \ src/aurora/herffile.h \ src/aurora/locstring.h \ src/aurora/gff3file.h \ src/aurora/gff4file.h \ src/aurora/gff4fields.h \ src/aurora/talktable.h \ src/aurora/talktable_tlk.h \ src/aurora/talktable_gff.h \ src/aurora/ssffile.h \ src/aurora/2dafile.h \ src/aurora/gdafile.h \ src/aurora/gdaheaders.h \ src/aurora/smallfile.h \ src/aurora/nitrofile.h \ src/aurora/nsbtxfile.h \ src/aurora/erfwriter.h \ $(EMPTY) src_aurora_libaurora_la_SOURCES += \ src/aurora/util.cpp \ src/aurora/language.cpp \ src/aurora/archive.cpp \ src/aurora/aurorafile.cpp \ src/aurora/erffile.cpp \ src/aurora/rimfile.cpp \ src/aurora/keyfile.cpp \ src/aurora/biffile.cpp \ src/aurora/ndsrom.cpp \ src/aurora/herffile.cpp \ src/aurora/locstring.cpp \ src/aurora/gff3file.cpp \ src/aurora/gff4file.cpp \ src/aurora/talktable.cpp \ src/aurora/talktable_tlk.cpp \ src/aurora/talktable_gff.cpp \ src/aurora/ssffile.cpp \ src/aurora/2dafile.cpp \ src/aurora/gdafile.cpp \ src/aurora/gdaheaders.cpp \ src/aurora/smallfile.cpp \ src/aurora/nitrofile.cpp \ src/aurora/nsbtxfile.cpp \ src/aurora/erfwriter.cpp \ $(EMPTY) xoreos-tools-0.0.5/src/aurora/smallfile.cpp000066400000000000000000000244621331663051500207400ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Decompressing "small" files, Nintendo DS LZSS (types 0x00 and 0x10), found in Sonic. */ #include "src/common/scopedptr.h" #include "src/common/error.h" #include "src/common/memreadstream.h" #include "src/common/memwritestream.h" #include "src/aurora/smallfile.h" namespace Aurora { static void readSmallHeader(Common::ReadStream &small, uint32 &type, uint32 &size) { uint32 data = small.readUint32LE(); type = data & 0x000000FF; size = data >> 8; } static void writeSmallHeader(Common::WriteStream &small, uint32 type, uint32 size) { type &= 0x000000FF; size &= 0x00FFFFFF; small.writeUint32LE((size << 8) | type); } static void decompress00(Common::ReadStream &small, Common::WriteStream &out, uint32 size) { out.writeStream(small, size); } static void compress00(Common::ReadStream &in, Common::WriteStream &small, uint32 size) { small.writeStream(in, size); } /* Simple LZSS 0x10 decompression. * * Code loosely based on DSDecmp by Barubary, released under the terms of the MIT license. * * See * and . */ static void decompress10(Common::ReadStream &small, Common::WriteStream &out, uint32 size) { byte buffer[0x10000]; uint32 bufferPos = 0; uint16 flags = 0xFF00; uint32 outSize = 0; while (outSize < size) { // Only our canaries left => Read flags for the next 8 blocks if (flags == 0xFF00) flags = (small.readByte() << 8) | 0x00FF; if (flags & 0x8000) { // Copy from buffer const byte data1 = small.readByte(); const byte data2 = small.readByte(); // Copy how many bytes from where (relative) in the buffer? const uint8 length = (data1 >> 4) + 3; const uint16 offset = (((data1 & 0x0F) << 8) | data2) + 1; // Direct offset. Add size of the buffer once, to protect from overroll uint32 copyOffset = bufferPos + sizeof(buffer) - offset; // Copy length bytes (and store each back into the buffer) for (uint8 i = 0; i < length; i++, copyOffset++) { if ((copyOffset % sizeof(buffer)) >= outSize) throw Common::Exception("Tried to copy past the buffer"); const byte data = buffer[copyOffset % sizeof(buffer)]; out.writeByte(data); outSize++; buffer[bufferPos] = data; bufferPos = (bufferPos + 1) % sizeof(buffer); } } else { // Read literal byte const byte data = small.readByte(); out.writeByte(data); outSize++; buffer[bufferPos] = data; bufferPos = (bufferPos + 1) % sizeof(buffer); } flags <<= 1; } if (outSize != size) throw Common::Exception("Invalid \"small\" data"); } /** Determine the maximum size of an LZSS-compressed block. * * Since this function supports continuously copying bytes from the "edge" * of the current compression pointer (which is the main difference between * LZSS and vanilla LZ77), both newPtr and oldPtr need to point into the * same memory region. * * Takes O(newLength * oldLength) = O(n^2) time. * * @param newPtr The start of the data that needs to be compressed. * @param newLength The number of bytes that still need to be compressed. * @param oldPtr The start of the raw file. * @param oldLength The number of bytes already compressed. * @param displacement The offset of the start of the longest block to refer to. * @param minDisplacement The minimum allowed value for a valid displacement. * @return The length of the longest sequence of bytes that can be copied from oldPtr. */ size_t getOccurrenceLength(const byte *newPtr, size_t newLength, const byte *oldPtr, size_t oldLength, size_t &displacement, size_t minDisplacement = 1) { displacement = 0; // Can we actually do anything with the data? if ((minDisplacement > oldLength) || (newLength == 0)) return 0; size_t maxLength = 0; for (size_t i = 0; i < oldLength - minDisplacement; i++) { /* Try out every single possible displacement value, from the * start of the old data to the end. */ const byte *currentOldPtr = oldPtr + i; size_t currentLength = 0; /* Determine the length we can copy if we go back (oldLength - i) bytes. * Always check the next newLength bytes, because we do LZSS. */ for (size_t j = 0; j < newLength; j++, currentLength++) if (currentOldPtr[j] != newPtr[j]) break; if (currentLength > maxLength) { // We've bettered our last try maxLength = currentLength; displacement = oldLength - i; // If we can't get any better than that, stop if (maxLength == newLength) break; } } return maxLength; } /* Simple LZSS 0x10 compression. * * Code loosely based on DSDecmp by Barubary, released under the terms of the MIT license. * * See * and . */ static void compress10(Common::ReadStream &in, Common::WriteStream &small, uint32 size) { Common::ScopedArray inBuffer(new byte[size]); if (in.read(inBuffer.get(), size) != size) throw Common::Exception(Common::kReadError); // Buffer for 8 blocks (max. 2 bytes each), plus their flags byte byte outBuffer[8 * 2 + 1] = { 0 }; size_t bufferedBlocks = 0, bufferLength = 1; size_t inRead = 0; while (inRead < size) { // If 8 blocks have been buffered, write them and reset the buffer if (bufferedBlocks == 8) { if (small.write(outBuffer, bufferLength) != bufferLength) throw Common::Exception(Common::kWriteError); bufferedBlocks = 0; bufferLength = 1; outBuffer[0] = 0x00; } /* Look for duplications in the input data: * Try to find an occurrence of data starting from the current place in the * data within the last 0x1000 bytes bytes (the maximum displacement the * format supports) of the already compressed data, but only check the next * 0x12 bytes (the maximum copy length). */ const size_t newLength = MIN(size - inRead, 0x12); const size_t oldLength = MIN(inRead, 0x1000); size_t displacement = 0; const size_t length = getOccurrenceLength(inBuffer.get() + inRead , newLength, inBuffer.get() + inRead - oldLength, oldLength, displacement); /* If the length of the occurrence is at least 3 bytes, we safe space by * referring to the earlier place in the data. If it's shorter (or even * non-existent), then just encode the next byte literally. */ if (length >= 3) { inRead += length; // Mark the block as compressed outBuffer[0] |= 1 << (7 - bufferedBlocks); outBuffer[bufferLength ] = ((length - 3) << 4) & 0xF0; outBuffer[bufferLength++] |= ((displacement - 1) >> 8) & 0x0F; outBuffer[bufferLength++] = (displacement - 1) & 0xFF; } else outBuffer[bufferLength++] = inBuffer[inRead++]; bufferedBlocks++; } // Write the remaining blocks if (bufferedBlocks > 0) if (small.write(outBuffer, bufferLength) != bufferLength) throw Common::Exception(Common::kWriteError); } static void decompress(Common::ReadStream &small, Common::WriteStream &out, uint32 type, uint32 size) { if (type == 0x00) decompress00(small, out, size); else if (type == 0x10) decompress10(small, out, size); else throw Common::Exception("Unsupported type 0x%08X", (uint) type); } void Small::decompress(Common::ReadStream &small, Common::WriteStream &out) { uint32 type, size; readSmallHeader(small, type, size); try { ::Aurora::decompress(small, out, type, size); } catch (Common::Exception &e) { e.add("Failed to decompress \"small\" file"); throw e; } } Common::SeekableReadStream *Small::decompress(Common::SeekableReadStream *small) { Common::ScopedPtr in(small); assert(in); uint32 type, size; readSmallHeader(*in, type, size); const size_t pos = in->pos(); if (type == 0x00) // Uncompressed. Just return a sub stream for the raw data return new Common::SeekableSubReadStream(in.release(), pos, pos + size, true); Common::MemoryWriteStreamDynamic out(true, size); try { ::Aurora::decompress(*in, out, type, size); } catch (Common::Exception &e) { e.add("Failed to decompress \"small\" file"); throw e; } out.setDisposable(false); return new Common::MemoryReadStream(out.getData(), out.size(), true); } Common::SeekableReadStream *Small::decompress(Common::ReadStream &small) { uint32 type, size; readSmallHeader(small, type, size); Common::MemoryWriteStreamDynamic out(true, size); try { ::Aurora::decompress(small, out, type, size); } catch (Common::Exception &e) { e.add("Failed to decompress \"small\" file"); throw e; } out.setDisposable(false); return new Common::MemoryReadStream(out.getData(), out.size(), true); } Common::SeekableReadStream *Small::decompress(Common::ReadStream *small) { Common::ScopedPtr in(small); assert(in); return decompress(*in); } void Small::compress00(Common::SeekableReadStream &in, Common::WriteStream &small) { const size_t size = in.size() - in.pos(); if (size >= 0xFFFFFF) throw Common::Exception("Small::compress00(): Input stream too large"); writeSmallHeader(small, 0x00, size); ::Aurora::compress00(in, small, size); } void Small::compress10(Common::SeekableReadStream &in, Common::WriteStream &small) { const size_t size = in.size() - in.pos(); if (size >= 0xFFFFFF) throw Common::Exception("Small::compress10(): Input stream too large"); writeSmallHeader(small, 0x10, size); ::Aurora::compress10(in, small, size); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/smallfile.h000066400000000000000000000044731331663051500204050ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Decompressing "small" files, Nintendo DS LZSS (types 0x00 and 0x10), found in Sonic. */ #ifndef AURORA_SMALLFILE_H #define AURORA_SMALLFILE_H namespace Common { class ReadStream; class SeekableReadStream; class WriteStream; } namespace Aurora { class Small { public: static void decompress(Common::ReadStream &small, Common::WriteStream &out); /** Decompress this stream into a new SeekableReadStream. */ static Common::SeekableReadStream *decompress(Common::ReadStream &small); /** Take over this stream and decompress it into a new SeekableReadStream. */ static Common::SeekableReadStream *decompress(Common::ReadStream *small); /** Take over this stream and decompress it into a new SeekableReadStream. * * If the Small files is uncompressed, this new stream will be a * SeekableSubReadStream simply wrapping the old stream. */ static Common::SeekableReadStream *decompress(Common::SeekableReadStream *small); /** "Compress" this stream into an uncompressed small file. * * This is basically just the input stream with a 4 byte header prepended. */ static void compress00(Common::SeekableReadStream &in, Common::WriteStream &small); /** Compress this stream into a small file of type 0x10. * * Note that, depending on the input data, the result may be bigger * that the input stream. */ static void compress10(Common::SeekableReadStream &in, Common::WriteStream &small); }; } // End of namespace Aurora #endif // AURORA_SMALLFILE_H xoreos-tools-0.0.5/src/aurora/ssffile.cpp000066400000000000000000000225131331663051500204160ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's SSFs (sound set file). */ /* See BioWare's own specs released for Neverwinter Nights modding * () */ #include "src/common/scopedptr.h" #include "src/common/readstream.h" #include "src/common/writestream.h" #include "src/common/writefile.h" #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/error.h" #include "src/common/encoding.h" #include "src/aurora/ssffile.h" static const uint32 kSSFID = MKTAG('S', 'S', 'F', ' '); static const uint32 kVersion10 = MKTAG('V', '1', '.', '0'); static const uint32 kVersion11 = MKTAG('V', '1', '.', '1'); namespace Aurora { SSFFile::Sound::Sound(const Common::UString &f, uint32 s) : soundFile(f), strRef(s) { } SSFFile::SSFFile() { } SSFFile::SSFFile(Common::SeekableReadStream &ssf) { load(ssf); } SSFFile::~SSFFile() { } void SSFFile::load(Common::SeekableReadStream &ssf) { try { size_t entryCount, offEntryTable; Version version = readSSFHeader(ssf, entryCount, offEntryTable); _sounds.resize(entryCount); readEntries(ssf, version, offEntryTable); } catch (Common::Exception &e) { e.add("Failed reading SSF file"); throw; } } SSFFile::Version SSFFile::readSSFHeader(Common::SeekableReadStream &ssf, size_t &entryCount, size_t &offEntryTable) { readHeader(ssf); if (_id != kSSFID) throw Common::Exception("Not a SSF file (%s)", Common::debugTag(_id).c_str()); if ((_version != kVersion10) && (_version != kVersion11)) throw Common::Exception("Unsupported SSF file version %s", Common::debugTag(_version).c_str()); entryCount = ssf.readUint32LE(); offEntryTable = ssf.readUint32LE(); if (entryCount >= UINT32_MAX) throw Common::Exception("Invalid SSF header"); // Plain old version V1.0 used in NWN (and NWN2) if (_version == kVersion10) return kVersion10_NWN; // NWN2's V1.1 if ((offEntryTable < ssf.size()) && ((ssf.size() - offEntryTable) >= ((4 + 32 + 4) * entryCount))) return kVersion11_NWN2; offEntryTable = entryCount; entryCount = (ssf.size() - offEntryTable) / 4; // Sanity check if ((offEntryTable > ssf.size()) || (((ssf.size() - offEntryTable) % 4) != 0)) throw Common::Exception("Invalid SSF header (%u, %u)", (uint32) ssf.size(), (uint32) offEntryTable); // KotOR's V1.1 return kVersion11_KotOR; } void SSFFile::readEntries(Common::SeekableReadStream &ssf, Version version, size_t offset) { ssf.seek(offset); switch (version) { case kVersion10_NWN: readEntriesNWN(ssf, 16); break; case kVersion11_NWN2: readEntriesNWN(ssf, 32); break; case kVersion11_KotOR: readEntriesKotOR(ssf); break; default: break; } } void SSFFile::readEntriesNWN(Common::SeekableReadStream &ssf, size_t soundFileLen) { /* The NWN/NWN2 versions of an SSF file (V1.0 and V1.1) begin with a list of offsets to the data entries. Each of these contains a ResRef of a sound file and a StrRef of a text. */ size_t count = _sounds.size(); std::vector offsets; offsets.resize(count); for (size_t i = 0; i < count; i++) offsets[i] = ssf.readUint32LE(); for (size_t i = 0; i < count; i++) { ssf.seek(offsets[i]); _sounds[i].soundFile = Common::readStringFixed(ssf, Common::kEncodingASCII, soundFileLen); _sounds[i].strRef = ssf.readUint32LE(); } } void SSFFile::readEntriesKotOR(Common::SeekableReadStream &ssf) { /* The KotOR/KotOR2 version of an SSF file (V1.1) is just a list of StrRefs. */ for (SoundSet::iterator sound = _sounds.begin(); sound != _sounds.end(); ++sound) sound->strRef = ssf.readUint32LE(); } size_t SSFFile::getSoundCount() const { return _sounds.size(); } const Common::UString &SSFFile::getSoundFile(size_t index) const { static const Common::UString kEmptyString = ""; if (index >= _sounds.size()) return kEmptyString; return _sounds[index].soundFile; } uint32 SSFFile::getStrRef(size_t index) const { if (index >= _sounds.size()) return kStrRefInvalid; return _sounds[index].strRef; } void SSFFile::getSound(size_t index, Common::UString &soundFile, uint32 &strRef) const { if (index >= _sounds.size()) { soundFile.clear(); strRef = kStrRefInvalid; return; } soundFile = _sounds[index].soundFile; strRef = _sounds[index].strRef; } void SSFFile::setSoundFile(size_t index, const Common::UString &soundFile) { if (index >= UINT32_MAX) throw Common::Exception("Sound index out of range"); if (_sounds.size() <= index) _sounds.resize(index + 1); _sounds[index].soundFile = soundFile; } void SSFFile::setStrRef(size_t index, uint32 strRef) { if (index >= UINT32_MAX) throw Common::Exception("Sound index out of range"); if (_sounds.size() <= index) _sounds.resize(index + 1); _sounds[index].strRef = strRef; } void SSFFile::setSound(size_t index, const Common::UString &soundFile, uint32 strRef) { if (index >= UINT32_MAX) throw Common::Exception("Sound index out of range"); if (_sounds.size() <= index) _sounds.resize(index + 1); _sounds[index].soundFile = soundFile; _sounds[index].strRef = strRef; } size_t SSFFile::getMaxSoundFileLen() const { size_t maxSoundFileLen = 0; for (SoundSet::const_iterator s = _sounds.begin(); s != _sounds.end(); ++s) maxSoundFileLen = MAX(maxSoundFileLen, s->soundFile.size()); return maxSoundFileLen; } bool SSFFile::existNonASCIISoundFile() const { for (SoundSet::const_iterator s = _sounds.begin(); s != _sounds.end(); ++s) for (Common::UString::iterator c = s->soundFile.begin(); c != s->soundFile.end(); ++c) if (!Common::UString::isASCII(*c)) return true; return false; } void SSFFile::checkVersionFeatures(Version version) const { assert(_sounds.size() < UINT32_MAX); if (existNonASCIISoundFile()) throw Common::Exception("SSF files do not support non-ASCII sound filenames"); const size_t maxFileLen = getMaxSoundFileLen(); switch (version) { case kVersion10_NWN: if (maxFileLen > 16) throw Common::Exception("Sound filenames in SSF V1.0 need to be 16 characters or less"); break; case kVersion11_NWN2: if (maxFileLen > 32) throw Common::Exception("Sound filenames in SSF V1.1 (NWN2) need to be 32 characters or less"); break; case kVersion11_KotOR: if (maxFileLen > 0) throw Common::Exception("SSF V1.1 (KotOR/KotOR2) does not support sound filenames"); break; default: throw Common::Exception("Invalid SSF version"); } } SSFFile::Version SSFFile::determineVersionForGame(GameID game) const { switch (game) { case kGameIDNWN: return kVersion10_NWN; case kGameIDNWN2: if (getMaxSoundFileLen() > 16) return kVersion11_NWN2; return kVersion10_NWN; case kGameIDKotOR: case kGameIDKotOR2: return kVersion11_KotOR; default: break; } throw Common::Exception("This game does not support SSF files"); } void SSFFile::writeSSF(Common::WriteStream &out, Version version) const { checkVersionFeatures(version); switch (version) { case kVersion10_NWN: writeNWN(out); break; case kVersion11_NWN2: writeNWN2(out); break; case kVersion11_KotOR: writeKotOR(out); break; } } bool SSFFile::writeSSF(const Common::UString &fileName, Version version) const { Common::WriteFile file; if (!file.open(fileName)) return false; writeSSF(file, version); file.close(); return true; } void SSFFile::writeNWN(Common::WriteStream &out, size_t soundFileLen) const { static const size_t kOffsetEntryTable = 0x28; out.writeUint32LE(_sounds.size()); out.writeUint32LE(kOffsetEntryTable); // Reserved for (size_t i = 16; i < kOffsetEntryTable; i++) out.writeByte(0); size_t offsetData = kOffsetEntryTable + _sounds.size() * 4; for (SoundSet::const_iterator s = _sounds.begin(); s != _sounds.end(); ++s, offsetData += soundFileLen + 4) { if (offsetData >= UINT32_MAX) throw Common::Exception(Common::kSeekError); out.writeUint32LE(offsetData); } for (SoundSet::const_iterator s = _sounds.begin(); s != _sounds.end(); ++s) { Common::writeStringFixed(out, s->soundFile, Common::kEncodingASCII, soundFileLen); out.writeUint32LE(s->strRef); } } void SSFFile::writeNWN(Common::WriteStream &out) const { out.writeString("SSF V1.0"); writeNWN(out, 16); } void SSFFile::writeNWN2(Common::WriteStream &out) const { out.writeString("SSF V1.1"); writeNWN(out, 32); } void SSFFile::writeKotOR(Common::WriteStream &out) const { out.writeString("SSF V1.1"); out.writeUint32LE(0x0C); // Offset to the entries for (SoundSet::const_iterator s = _sounds.begin(); s != _sounds.end(); ++s) out.writeUint32LE(s->strRef); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/ssffile.h000066400000000000000000000121241331663051500200600ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's SSFs (sound set file). */ #ifndef AURORA_SSFFILE_H #define AURORA_SSFFILE_H #include #include "src/common/types.h" #include "src/common/ustring.h" #include "src/aurora/types.h" #include "src/aurora/aurorafile.h" namespace Common { class SeekableReadStream; class WriteStream; } namespace Aurora { /** Class to hold a sound set. * * A sound set contains a simple array of strings and sound resource * names for common creature sounds, like fighting noises, being * hurt, calling for medical help, etc. * * Which index is used for which situation differs from game to game. * * SSF files are used in these four games: Neverwinter Nights, * Neverwinter Nights 2, Knights of the Old Republic and Knights * of the Old Republic II. */ class SSFFile : public AuroraFile { public: /** The different versions of SSF files that exists. */ enum Version { kVersion10_NWN, ///< SSF V1.0, as found in NWN and NWN2. kVersion11_NWN2, ///< SSF V1.1, as found in NWN2. kVersion11_KotOR ///< SSF V1.1, as found in KotOR and KotOR. }; SSFFile(); SSFFile(Common::SeekableReadStream &ssf); ~SSFFile(); /** Return the number of sounds in this SSF file. */ size_t getSoundCount() const; // .--- Reading sounds from the sound set /** Return the sound file to play for this sound. */ const Common::UString &getSoundFile(size_t index) const; /** Return the string reference of the text to display for this sound. */ uint32 getStrRef(size_t index) const; /** Return both the sound file and the string reference for this sound. */ void getSound(size_t index, Common::UString &soundFile, uint32 &strRef) const; // '--- // .--- Writing sounds to the sound set /** Set the sound file to play for this sound. */ void setSoundFile(size_t index, const Common::UString &soundFile); /** Set the string reference of the text to display for this sound. */ void setStrRef(size_t index, uint32 strRef); /** Set both the sound file and the string reference for this sound. */ void setSound(size_t index, const Common::UString &soundFile, uint32 strRef); // '--- // .--- Writing SSF files /** Determine the best version to save this SSF file in, for the specified game. */ Version determineVersionForGame(GameID game) const; /** Write the SSF into a stream, as the specified version. */ void writeSSF(Common::WriteStream &out, Version version) const; /** Write the SSF into a file, as the specified version. */ bool writeSSF(const Common::UString &fileName, Version version) const; // '--- private: /** A sound in the sound set. */ struct Sound { Common::UString soundFile; ///< The name of the sound file to play. uint32 strRef; ///< StrRef of the text to display. Sound(const Common::UString &f = "", uint32 s = kStrRefInvalid); }; typedef std::vector SoundSet; SoundSet _sounds; void load(Common::SeekableReadStream &ssf); /** Read the header of an SSF file and determine the version. */ Version readSSFHeader(Common::SeekableReadStream &ssf, size_t &entryCount, size_t &offEntryTable); /** Read the data entries, depending on the version. */ void readEntries(Common::SeekableReadStream &ssf, Version version, size_t offset); /** Read the data entries of the NWN versions. */ void readEntriesNWN(Common::SeekableReadStream &ssf, size_t soundFileLen); /** Read the data entries of the KotOR version. */ void readEntriesKotOR(Common::SeekableReadStream &ssf); /** Return the maximum length of a sound filename in characters. */ size_t getMaxSoundFileLen() const; /** Is there a sound filename with non-ASCII characters? */ bool existNonASCIISoundFile() const; /** Make sure this SSF files fits the requirements for specified SSF version. */ void checkVersionFeatures(Version version) const; /** Write this SSF into a stream as a V1.0 (NWN). */ void writeNWN(Common::WriteStream &out) const; /** Write this SSF into a stream as a V1.1 (NWN2). */ void writeNWN2(Common::WriteStream &out) const; /** Write this SSF into a stream as a V1.1 (KotOR/KotOR2). */ void writeKotOR(Common::WriteStream &out) const; /** Write this SSF data into a stream as one of the versions for NWN. */ void writeNWN(Common::WriteStream &out, size_t soundFileLen) const; }; } // End of namespace Aurora #endif // AURORA_SSFFILE_H xoreos-tools-0.0.5/src/aurora/talktable.cpp000066400000000000000000000040601331663051500207230ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Base class for BioWare's talk tables. */ #include "src/common/util.h" #include "src/common/scopedptr.h" #include "src/common/readstream.h" #include "src/aurora/aurorafile.h" #include "src/aurora/talktable.h" #include "src/aurora/talktable_tlk.h" #include "src/aurora/talktable_gff.h" #include "src/aurora/language.h" static const uint32 kTLKID = MKTAG('T', 'L', 'K', ' '); static const uint32 kGFFID = MKTAG('G', 'F', 'F', ' '); namespace Aurora { TalkTable::TalkTable(Common::Encoding encoding) : _encoding(encoding) { } TalkTable::~TalkTable() { } uint32 TalkTable::getLanguageID() const { return kLanguageInvalid; } void TalkTable::setLanguageID(uint32 UNUSED(id)) { } TalkTable *TalkTable::load(Common::SeekableReadStream *tlk, Common::Encoding encoding) { Common::ScopedPtr tlkStream(tlk); if (!tlkStream) return 0; size_t pos = tlkStream->pos(); uint32 id, version; bool utf16le; AuroraFile::readHeader(*tlkStream, id, version, utf16le); tlkStream->seek(pos); if (id == kTLKID) return new TalkTable_TLK(tlkStream.release(), encoding); if (id == kGFFID) return new TalkTable_GFF(tlkStream.release(), encoding); return 0; } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/talktable.h000066400000000000000000000053021331663051500203700ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Base class for BioWare's talk tables. */ #ifndef AURORA_TALKTABLE_H #define AURORA_TALKTABLE_H #include #include #include "src/common/types.h" #include "src/common/encoding.h" namespace Common { class UString; class SeekableReadStream; } namespace Aurora { /** Base class for BioWare's talk tables. * * A talk table contains localized string data, and optional voice- * over resource names, indexed by a string reference ("StrRef"). * * A single talktable always contains strings in a single language * (and for a single gender of the PC), and commonly all strings for * a given context (module, campaign, ...). * * See classes TalkTable_TLK and TalkTable_GFF for the two main * formats a talk table can be found in. */ class TalkTable : boost::noncopyable { public: virtual ~TalkTable(); virtual uint32 getLanguageID() const; virtual void setLanguageID(uint32 id); virtual const std::list &getStrRefs() const = 0; virtual bool getString(uint32 strRef, Common::UString &string, Common::UString &soundResRef) const = 0; virtual bool getEntry(uint32 strRef, Common::UString &string, Common::UString &soundResRef, uint32 &volumeVariance, uint32 &pitchVariance, float &soundLength, uint32 &soundID) const = 0; virtual void setEntry(uint32 strRef, const Common::UString &string, const Common::UString &soundResRef, uint32 volumeVariance, uint32 pitchVariance, float soundLength, uint32 soundID) = 0; /** Take over this stream and read a talk table (of either format) out of it. */ static TalkTable *load(Common::SeekableReadStream *tlk, Common::Encoding encoding); protected: TalkTable(Common::Encoding encoding); Common::Encoding _encoding; }; } // End of namespace Aurora #endif // AURORA_TALKTABLE_H xoreos-tools-0.0.5/src/aurora/talktable_gff.cpp000066400000000000000000000161061331663051500215510ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's GFF'd talk tables. */ /* See the TLK description on the Dragon Age toolset wiki * (). */ #include #include "src/common/util.h" #include "src/common/error.h" #include "src/common/readstream.h" #include "src/aurora/talktable_gff.h" #include "src/aurora/gff4file.h" static const uint32 kTLKID = MKTAG('T', 'L', 'K', ' '); static const uint32 kVersion02 = MKTAG('V', '0', '.', '2'); static const uint32 kVersion05 = MKTAG('V', '0', '.', '5'); namespace Aurora { TalkTable_GFF::TalkTable_GFF(Common::SeekableReadStream *tlk, Common::Encoding encoding) : TalkTable(encoding) { if (_encoding == Common::kEncodingInvalid) _encoding = Common::kEncodingUTF16LE; load(tlk); } TalkTable_GFF::~TalkTable_GFF() { } const std::list &TalkTable_GFF::getStrRefs() const { return _strRefs; } bool TalkTable_GFF::getString(uint32 strRef, Common::UString &string, Common::UString &soundResRef) const { Entries::const_iterator e = _entries.find(strRef); if (e == _entries.end()) return false; string = readString(*e->second); soundResRef = ""; return true; } bool TalkTable_GFF::getEntry(uint32 strRef, Common::UString &string, Common::UString &soundResRef, uint32 &volumeVariance, uint32 &pitchVariance, float &soundLength, uint32 &soundID) const { Entries::const_iterator e = _entries.find(strRef); if (e == _entries.end()) return false; string = readString(*e->second); soundResRef = ""; volumeVariance = 0; pitchVariance = 0; soundLength = -1.0f; soundID = 0xFFFFFFFF; return true; } void TalkTable_GFF::setEntry(uint32 strRef, const Common::UString &string, const Common::UString &UNUSED(soundResRef), uint32 UNUSED(volumeVariance), uint32 UNUSED(pitchVariance), float UNUSED(soundLength), uint32 UNUSED(soundID)) { Entries::iterator entry = _entries.find(strRef); if (entry == _entries.end()) { std::pair result = _entries.insert(std::make_pair(strRef, new Entry)); entry = result.first; _strRefs.push_back(strRef); } entry->second->text = string; } void TalkTable_GFF::load(Common::SeekableReadStream *tlk) { assert(tlk); try { _gff.reset(new GFF4File(tlk, kTLKID)); const GFF4Struct &top = _gff->getTopLevel(); if (_gff->getTypeVersion() == kVersion02) load02(top); else if (_gff->getTypeVersion() == kVersion05) load05(top); else throw Common::Exception("Unsupported GFF TLK file version %08X", _gff->getTypeVersion()); _strRefs.sort(); } catch (Common::Exception &e) { e.add("Unable to load GFF TLK"); throw; } } void TalkTable_GFF::load02(const GFF4Struct &top) { if (!top.hasField(kGFF4TalkStringList)) return; const GFF4List &strings = top.getList(kGFF4TalkStringList); for (GFF4List::const_iterator s = strings.begin(); s != strings.end(); ++s) { if (!*s) continue; uint32 strRef = (*s)->getUint(kGFF4TalkStringID, 0xFFFFFFFF); if (strRef == 0xFFFFFFFF) continue; Common::ScopedPtr entry(new Entry(*s)); std::pair result = _entries.insert(std::make_pair(strRef, entry.get())); if (result.second) entry.release(); _strRefs.push_back(strRef); } } void TalkTable_GFF::load05(const GFF4Struct &top) { if (!top.hasField(kGFF4HuffTalkStringList) || !top.hasField(kGFF4HuffTalkStringHuffTree) || !top.hasField(kGFF4HuffTalkStringBitStream)) return; const GFF4List &strings = top.getList(kGFF4HuffTalkStringList); for (GFF4List::const_iterator s = strings.begin(); s != strings.end(); ++s) { if (!*s) continue; uint32 strRef = (*s)->getUint(kGFF4HuffTalkStringID, 0xFFFFFFFF); if (strRef == 0xFFFFFFFF) continue; Common::ScopedPtr entry(new Entry(*s)); std::pair result = _entries.insert(std::make_pair(strRef, entry.get())); if (result.second) entry.release(); _strRefs.push_back(strRef); } } Common::UString TalkTable_GFF::readString(const Entry &entry) const { if (!entry.text.empty()) return entry.text; if (!entry.strct) return ""; if (_gff->getTypeVersion() == kVersion02) return readString02(entry); else if (_gff->getTypeVersion() == kVersion05) return readString05(entry); return ""; } Common::UString TalkTable_GFF::readString02(const Entry &entry) const { if (_encoding == Common::kEncodingInvalid) return "[???]"; return entry.strct->getString(kGFF4TalkString, _encoding); } Common::UString TalkTable_GFF::readString05(const Entry &entry) const { Common::ScopedPtr huffTree (_gff->getTopLevel().getData(kGFF4HuffTalkStringHuffTree)), bitStream(_gff->getTopLevel().getData(kGFF4HuffTalkStringBitStream)); Common::UString str = readString05(huffTree.get(), bitStream.get(), entry); return str; } Common::UString TalkTable_GFF::readString05(Common::SeekableReadStream *huffTree, Common::SeekableReadStream *bitStream, const Entry &entry) const { if (!huffTree || !bitStream) return ""; /* Read a string encoded in a Huffman'd bitstream. * * The Huffman tree itself is made up of signed 32bit nodes: * - Positive values are internal nodes, encoding a child index * - Negative values are leaf nodes, encoding an UTF-16 character value * * Kudos to Rick (gibbed) (). */ std::vector utf16Str; const uint32 startOffset = entry.strct->getUint(kGFF4HuffTalkStringBitOffset); uint32 index = startOffset >> 5; uint32 shift = startOffset & 0x1F; do { ptrdiff_t e = (huffTree->size() / 8) - 1; while (e >= 0) { bitStream->seek(index * 4); const ptrdiff_t offset = (bitStream->readUint32LE() >> shift) & 1; huffTree->seek(((e * 2) + offset) * 4); e = huffTree->readSint32LE(); shift++; index += (shift >> 5); shift %= 32; } utf16Str.push_back(TO_LE_16(0xFFFF - e)); } while (utf16Str.back() != 0); const byte *data = reinterpret_cast(&utf16Str[0]); const size_t size = utf16Str.size() * 2; return Common::readString(data, size, Common::kEncodingUTF16LE); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/talktable_gff.h000066400000000000000000000064441331663051500212220ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's GFF'd talk tables. */ #ifndef AURORA_TALKTABLE_GFF_H #define AURORA_TALKTABLE_GFF_H #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/ptrmap.h" #include "src/common/ustring.h" #include "src/aurora/types.h" #include "src/aurora/talktable.h" namespace Aurora { /** Loading BioWare's GFF'd talk tables. * * See class TalkTable for a general overview how talk tables work. * * Unlike TalkTable_TLK, a GFF talk table stores the string data * within a V4.0 GFF. It does not store any language ID (the language * is implicit in the talk tables file name), nor any other data * besides the raw strings. getSoundResRef() always returns an empty * string. * * There are two versions of GFF'd talk tables known and supported * - V0.2, used by Sonic Chronicles and Dragon Age: Origins * - V0.5, used by Dragon Age II */ class TalkTable_GFF : public TalkTable { public: /** Take over this stream and read a GFF'd TLK out of it. */ TalkTable_GFF(Common::SeekableReadStream *tlk, Common::Encoding encoding); ~TalkTable_GFF(); const std::list &getStrRefs() const; bool getString(uint32 strRef, Common::UString &string, Common::UString &soundResRef) const; bool getEntry(uint32 strRef, Common::UString &string, Common::UString &soundResRef, uint32 &volumeVariance, uint32 &pitchVariance, float &soundLength, uint32 &soundID) const; void setEntry(uint32 strRef, const Common::UString &string, const Common::UString &soundResRef, uint32 volumeVariance, uint32 pitchVariance, float soundLength, uint32 soundID); private: struct Entry { Common::UString text; const GFF4Struct *strct; Entry(const GFF4Struct *s = 0) : strct(s) { } }; typedef Common::PtrMap Entries; Common::ScopedPtr _gff; std::list _strRefs; Entries _entries; void load(Common::SeekableReadStream *tlk); void load02(const GFF4Struct &top); void load05(const GFF4Struct &top); Common::UString readString(const Entry &entry) const; Common::UString readString02(const Entry &entry) const; Common::UString readString05(const Entry &entry) const; Common::UString readString05(Common::SeekableReadStream *huffTree, Common::SeekableReadStream *bitStream, const Entry &entry) const; }; } // End of namespace Aurora #endif // AURORA_TALKTABLE_GFF_H xoreos-tools-0.0.5/src/aurora/talktable_tlk.cpp000066400000000000000000000236151331663051500216040ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's TLK talk tables. */ /* See BioWare's own specs released for Neverwinter Nights modding * () */ #include #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/memreadstream.h" #include "src/common/memwritestream.h" #include "src/common/readfile.h" #include "src/common/error.h" #include "src/aurora/talktable_tlk.h" #include "src/aurora/language.h" static const uint32 kTLKID = MKTAG('T', 'L', 'K', ' '); static const uint32 kVersion3 = MKTAG('V', '3', '.', '0'); static const uint32 kVersion4 = MKTAG('V', '4', '.', '0'); namespace Aurora { TalkTable_TLK::Entry::Entry() : offset(0xFFFFFFFF), length(0xFFFFFFFF), flags(0), volumeVariance(0), pitchVariance(0), soundLength(-1.0f), soundID(0xFFFFFFFF) { } TalkTable_TLK::TalkTable_TLK(Common::Encoding encoding, uint32 languageID) : TalkTable(encoding), _tlk(0), _languageID(languageID) { } TalkTable_TLK::TalkTable_TLK(Common::SeekableReadStream *tlk, Common::Encoding encoding) : TalkTable(encoding), _tlk(tlk) { assert(_tlk); load(); } TalkTable_TLK::~TalkTable_TLK() { } void TalkTable_TLK::load() { try { readHeader(*_tlk); if (_id != kTLKID) throw Common::Exception("Not a TLK file (%s)", Common::debugTag(_id).c_str()); if (_version != kVersion3 && _version != kVersion4) throw Common::Exception("Unsupported TLK file version %s", Common::debugTag(_version).c_str()); _languageID = _tlk->readUint32LE(); if (_encoding == Common::kEncodingInvalid) _encoding = LangMan.getEncoding(LangMan.getLanguage(_languageID)); if (_encoding == Common::kEncodingInvalid) _encoding = Common::kEncodingCP1252; uint32 stringCount = _tlk->readUint32LE(); _entries.resize(stringCount); // V4 added this field; it's right after the header in V3 uint32 tableOffset = 20; if (_version == kVersion4) tableOffset = _tlk->readUint32LE(); const uint32 stringsOffset = _tlk->readUint32LE(); // Go to the table _tlk->seek(tableOffset); // Read in all the table data if (_version == kVersion3) readEntryTableV3(stringsOffset); else readEntryTableV4(); } catch (Common::Exception &e) { e.add("Failed reading TLK file"); throw; } } void TalkTable_TLK::readEntryTableV3(uint32 stringsOffset) { for (size_t i = 0; i < _entries.size(); i++) { Entry &entry = _entries[i]; entry.flags = _tlk->readUint32LE(); entry.soundResRef = Common::readStringFixed(*_tlk, Common::kEncodingASCII, 16); entry.volumeVariance = _tlk->readUint32LE(); entry.pitchVariance = _tlk->readUint32LE(); entry.offset = _tlk->readUint32LE() + stringsOffset; entry.length = _tlk->readUint32LE(); entry.soundLength = _tlk->readIEEEFloatLE(); if (!(entry.flags & kFlagSoundLengthPresent)) entry.soundLength = -1.0f; if (((entry.length > 0) && (entry.flags & kFlagTextPresent)) || (!entry.soundResRef.empty())) _strRefs.push_back(i); } } void TalkTable_TLK::readEntryTableV4() { for (size_t i = 0; i < _entries.size(); i++) { Entry &entry = _entries[i]; entry.soundID = _tlk->readUint32LE(); entry.offset = _tlk->readUint32LE(); entry.length = _tlk->readUint16LE(); entry.flags = kFlagTextPresent; if (((entry.length > 0) && (entry.flags & kFlagTextPresent)) || (entry.soundID != 0xFFFFFFFF)) _strRefs.push_back(i); } } Common::UString TalkTable_TLK::readString(const Entry &entry) const { if (!_tlk || !entry.text.empty()) return entry.text; if ((entry.length == 0) || !(entry.flags & kFlagTextPresent)) return ""; if (_encoding == Common::kEncodingInvalid) return ""; _tlk->seek(entry.offset); size_t length = MIN(entry.length, _tlk->size() - _tlk->pos()); if (length == 0) return ""; Common::ScopedPtr data(_tlk->readStream(length)); Common::ScopedPtr parsed(LangMan.preParseColorCodes(*data)); return Common::readString(*parsed, _encoding); } uint32 TalkTable_TLK::getLanguageID() const { return _languageID; } void TalkTable_TLK::setLanguageID(uint32 id) { _languageID = id; } const std::list &TalkTable_TLK::getStrRefs() const { return _strRefs; } bool TalkTable_TLK::getString(uint32 strRef, Common::UString &string, Common::UString &soundResRef) const { if (strRef >= _entries.size()) return false; string = readString(_entries[strRef]); soundResRef = _entries[strRef].soundResRef; return true; } bool TalkTable_TLK::getEntry(uint32 strRef, Common::UString &string, Common::UString &soundResRef, uint32 &volumeVariance, uint32 &pitchVariance, float &soundLength, uint32 &soundID) const { if (strRef >= _entries.size()) return false; const Entry &entry = _entries[strRef]; string = readString(entry); soundResRef = entry.soundResRef; volumeVariance = entry.volumeVariance; pitchVariance = entry.pitchVariance; soundLength = entry.soundLength; soundID = entry.soundID; return true; } void TalkTable_TLK::setEntry(uint32 strRef, const Common::UString &string, const Common::UString &soundResRef, uint32 volumeVariance, uint32 pitchVariance, float soundLength, uint32 soundID) { if (strRef >= _entries.size()) { for (size_t i = _entries.size(); i < strRef; i++) _strRefs.push_back(i); _strRefs.sort(); _strRefs.unique(); _entries.resize(strRef + 1); } Entry &entry = _entries[strRef]; entry.text = string; entry.soundResRef = soundResRef; entry.volumeVariance = volumeVariance; entry.pitchVariance = pitchVariance; entry.soundLength = soundLength; entry.soundID = soundID; entry.length = 0; entry.offset = 0xFFFFFFFF; entry.flags = 0; if (!entry.text.empty()) entry.flags |= kFlagTextPresent; if (!entry.soundResRef.empty()) entry.flags |= kFlagSoundPresent; if (entry.soundLength > 0.0f) entry.flags |= kFlagSoundLengthPresent; } Common::SeekableReadStream *TalkTable_TLK::collectEntries(Entries &entries) const { entries.resize(_entries.size()); Common::MemoryWriteStreamDynamic data; try { for (size_t i = 0; i < _entries.size(); i++) { entries[i].length = 0; entries[i].offset = 0; const Common::UString text = readString(_entries[i]); if (!text.empty()) { entries[i].offset = data.size(); entries[i].length = Common::writeString(data, text, _encoding, false); } entries[i].soundResRef = _entries[i].soundResRef; entries[i].volumeVariance = _entries[i].volumeVariance; entries[i].pitchVariance = _entries[i].pitchVariance; entries[i].soundLength = _entries[i].soundLength; entries[i].soundID = _entries[i].soundID; entries[i].flags = 0; if (entries[i].length > 0) entries[i].flags |= kFlagTextPresent; if (!entries[i].soundResRef.empty()) entries[i].flags |= kFlagSoundPresent; if (entries[i].soundLength >= 0.0f) entries[i].flags |= kFlagSoundLengthPresent; } } catch (...) { data.dispose(); throw; } return new Common::MemoryReadStream(data.getData(), data.size(), true); } void TalkTable_TLK::write30(Common::WriteStream &out) const { out.writeUint32BE(kTLKID); out.writeUint32BE(kVersion3); out.writeUint32LE(_languageID); Entries entries; Common::ScopedPtr data(collectEntries(entries)); const uint32 stringsOffset = 20 + entries.size() * 40; out.writeUint32LE(entries.size()); out.writeUint32LE(stringsOffset); for (Entries::const_iterator e = entries.begin(); e != entries.end(); ++e) { out.writeUint32LE(e->flags); Common::writeStringFixed(out, e->soundResRef, Common::kEncodingASCII, 16); out.writeUint32LE(e->volumeVariance); out.writeUint32LE(e->pitchVariance); out.writeUint32LE(e->offset); out.writeUint32LE(e->length); out.writeIEEEFloatLE(MAX(0.0f, e->soundLength)); } out.writeStream(*data); } void TalkTable_TLK::write40(Common::WriteStream &out) const { out.writeUint32BE(kTLKID); out.writeUint32BE(kVersion4); out.writeUint32LE(_languageID); Entries entries; Common::ScopedPtr data(collectEntries(entries)); const uint32 stringsOffset = 32 + entries.size() * 10; out.writeUint32LE(entries.size()); // Offset to the string table. We'll put it right after the header, with some padding out.writeUint32LE(32); out.writeUint32LE(stringsOffset); // Padding out.writeUint32LE(0); out.writeUint32LE(0); for (Entries::const_iterator e = entries.begin(); e != entries.end(); ++e) { out.writeUint32LE(e->soundID); out.writeUint32LE(e->offset + stringsOffset); out.writeUint16LE(e->length); } out.writeStream(*data); } uint32 TalkTable_TLK::getLanguageID(Common::SeekableReadStream &tlk) { uint32 id, version; bool utf16le; AuroraFile::readHeader(tlk, id, version, utf16le); if ((id != kTLKID) || ((version != kVersion3) && (version != kVersion4))) return kLanguageInvalid; return tlk.readUint32LE(); } uint32 TalkTable_TLK::getLanguageID(const Common::UString &file) { Common::ReadFile tlk; if (!tlk.open(file)) return kLanguageInvalid; return getLanguageID(tlk); } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/talktable_tlk.h000066400000000000000000000102421331663051500212410ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Handling BioWare's TLK talk tables. */ #ifndef AURORA_TALKTABLE_TLK_H #define AURORA_TALKTABLE_TLK_H #include #include "src/common/types.h" #include "src/common/scopedptr.h" #include "src/common/ustring.h" #include "src/aurora/aurorafile.h" #include "src/aurora/talktable.h" namespace Common { class WriteStream; } namespace Aurora { /** Loading BioWare's TLK talk tables. * * See class TalkTable for a general overview how talk tables work. * * Unlike TalkTable_GFF, a TLK talk table is its own simple binary * format. It has a numerical, game-local ID of the language it * contains, and stores a few more optional data points per string, * like a reference to a voice-over file. * * There are two versions of TLK files known and supported * - V3.0, used by Neverwinter Nights, Neverwinter Nights 2, Knight of * the Old Republic, Knight of the Old Republic II and The Witcher * - V4.0, used by Jade Empire */ class TalkTable_TLK : public AuroraFile, public TalkTable { public: TalkTable_TLK(Common::Encoding encoding, uint32 languageID); /** Take over this stream and read a TLK out of it. */ TalkTable_TLK(Common::SeekableReadStream *tlk, Common::Encoding encoding); ~TalkTable_TLK(); /** Return the language ID (ungendered) of the talk table. */ uint32 getLanguageID() const; /** Set the language ID (ungendered) of the talk table. */ void setLanguageID(uint32 id); const std::list &getStrRefs() const; bool getString(uint32 strRef, Common::UString &string, Common::UString &soundResRef) const; /** Return all values associated to a string references in a TLK talk table. */ bool getEntry(uint32 strRef, Common::UString &string, Common::UString &soundResRef, uint32 &volumeVariance, uint32 &pitchVariance, float &soundLength, uint32 &soundID) const; /** Modify or add an entry to the talk table. */ void setEntry(uint32 strRef, const Common::UString &string, const Common::UString &soundResRef, uint32 volumeVariance, uint32 pitchVariance, float soundLength, uint32 soundID); /** Write this TLK as a version V3.0 TLK into that stream. */ void write30(Common::WriteStream &out) const; /** Write this TLK as a version V4.0 TLK into that stream. */ void write40(Common::WriteStream &out) const; static uint32 getLanguageID(Common::SeekableReadStream &tlk); static uint32 getLanguageID(const Common::UString &file); private: /** The entries' flags. */ enum EntryFlags { kFlagTextPresent = (1 << 0), kFlagSoundPresent = (1 << 1), kFlagSoundLengthPresent = (1 << 2) }; /** A talk resource entry. */ struct Entry { Common::UString text; uint32 offset; uint32 length; // V3 uint32 flags; Common::UString soundResRef; uint32 volumeVariance; // Unused uint32 pitchVariance; // Unused float soundLength; // In seconds // V4 uint32 soundID; Entry(); }; typedef std::vector Entries; Common::ScopedPtr _tlk; uint32 _languageID; std::list _strRefs; Entries _entries; void load(); void readEntryTableV3(uint32 stringsOffset); void readEntryTableV4(); Common::UString readString(const Entry &entry) const; Common::SeekableReadStream *collectEntries(Entries &entries) const; }; } // End of namespace Aurora #endif // AURORA_TALKTABLE_TLK_H xoreos-tools-0.0.5/src/aurora/types.h000066400000000000000000000474101331663051500175770ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Basic type definitions to handle files used in BioWare's Aurora engine. */ #ifndef AURORA_TYPES_H #define AURORA_TYPES_H #include #include "src/common/types.h" namespace Aurora { /** Various file types used by the Aurora engine and found in archives. * * Many archive formats used by the Aurora engine games do not contain * full filenames for the files contained within. Instead, they only * provide the stem of the filename, i.e. the file name without the file * extension. Additionally, they contain a type ID, which maps to the * enum values below. * * Please note, however, that all IDs >= 19000 aren't found in such * archives. These are arbitrary numbers for files that are only found * as plain files in the file system, or inside archives that do not * use numerical type IDs. Should such a file ever be found in an archive * with a type ID, this dummy entry in the block of IDs >= 19000 needs to * be deleted, and a real entry with the correct ID should be added * instead. * * If there's a collision between types, if one game re-uses a type ID * for a different file type, the new ID needs to be added to he block * of IDs >= 19000, and the conflicting file type should be added to the * method FileTypeManager::aliasFileType(). A tool that needs to be able * to correctly differentiate between these aliased file types can call * this method to do so. If necessary, a command line switch to explictly * select the game can be added to the tool. */ enum FileType { kFileTypeNone = - 1, kFileTypeRES = 0, ///< Generic GFF. kFileTypeBMP = 1, ///< Image, Windows bitmap. kFileTypeMVE = 2, ///< Video, Infinity Engine. kFileTypeTGA = 3, ///< Image, Truevision TARGA image. kFileTypeWAV = 4, ///< Audio, Waveform. kFileTypePLT = 6, ///< Packed layer texture. kFileTypeINI = 7, ///< Configuration, Windows INI. kFileTypeBMU = 8, ///< Audio, MP3 with extra header. kFileTypeMPG = 9, ///< Video, MPEG. kFileTypeTXT = 10, ///< Text, raw. kFileTypeWMA = 11, ///< Audio, Windows media. kFileTypeWMV = 12, ///< Video, Windows media. kFileTypeXMV = 13, ///< Video, Xbox. kFileTypePLH = 2000, kFileTypeTEX = 2001, ///< Texture. kFileTypeMDL = 2002, ///< Geometry, BioWare model. kFileTypeTHG = 2003, kFileTypeFNT = 2005, ///< Font. kFileTypeLUA = 2007, ///< Script, LUA source. kFileTypeSLT = 2008, kFileTypeNSS = 2009, ///< Script, NWScript source. kFileTypeNCS = 2010, ///< Script, NWScript bytecode. kFileTypeMOD = 2011, ///< Module, ERF. kFileTypeARE = 2012, ///< Static area data, GFF. kFileTypeSET = 2013, ///< Tileset. kFileTypeIFO = 2014, ///< Module information, GFF. kFileTypeBIC = 2015, ///< Character data, GFF. kFileTypeWOK = 2016, ///< Walk mesh. kFileType2DA = 2017, ///< Table data, 2-dimensional text array. kFileTypeTLK = 2018, ///< Talk table. kFileTypeTXI = 2022, ///< Texture information. kFileTypeGIT = 2023, ///< Dynamic area data, GFF. kFileTypeBTI = 2024, ///< Item template (BioWare), GFF. kFileTypeUTI = 2025, ///< Item template (user), GFF. kFileTypeBTC = 2026, ///< Creature template (BioWare), GFF. kFileTypeUTC = 2027, ///< Creature template (user), GFF. kFileTypeDLG = 2029, ///< Dialog tree, GFF. kFileTypeITP = 2030, ///< Toolset "palette" (tree of tiles or object templates), GFF. kFileTypeBTT = 2031, ///< Trigger template (BioWare), GFF. kFileTypeUTT = 2032, ///< Trigger template (user), GFF. kFileTypeDDS = 2033, ///< Texture, DirectDraw Surface. kFileTypeBTS = 2034, ///< Sound template (BioWare), GFF. kFileTypeUTS = 2035, ///< Sound template (user), GFF. kFileTypeLTR = 2036, ///< Letter combo probability information. kFileTypeGFF = 2037, ///< Generic GFF. kFileTypeFAC = 2038, ///< Faction information, GFF. kFileTypeBTE = 2039, ///< Encounter template (BioWare), GFF. kFileTypeUTE = 2040, ///< Encounter template (user), GFF. kFileTypeBTD = 2041, ///< Door template (BioWare), GFF. kFileTypeUTD = 2042, ///< Door template (user), GFF. kFileTypeBTP = 2043, ///< Placeable template (BioWare), GFF. kFileTypeUTP = 2044, ///< Placeable template (user), GFF. kFileTypeDFT = 2045, ///< Default values. kFileTypeDTF = 2045, ///< Default value file, INI. kFileTypeGIC = 2046, ///< Game instance comments, GFF. kFileTypeGUI = 2047, ///< GUI definition, GFF. kFileTypeCSS = 2048, ///< Script, conditional source script. kFileTypeCCS = 2049, ///< Script, conditional compiled script. kFileTypeBTM = 2050, ///< Store template (BioWare), GFF. kFileTypeUTM = 2051, ///< Store template (user), GFF. kFileTypeDWK = 2052, ///< Door walk mesh. kFileTypePWK = 2053, ///< Placeable walk mesh. kFileTypeBTG = 2054, ///< Random item generator template (BioWare), GFF. kFileTypeUTG = 2055, ///< Random item generator template (user), GFF. kFileTypeJRL = 2056, ///< Journal data, GFF. kFileTypeSAV = 2057, ///< Game save, ERF. kFileTypeUTW = 2058, ///< Waypoint template, GFF. kFileType4PC = 2059, ///< Texture, custom 16-bit RGBA. kFileTypeSSF = 2060, ///< Sound Set File. kFileTypeHAK = 2061, ///< Resource hak pak, ERF. kFileTypeNWM = 2062, ///< Neverwinter Nights original campaign module, ERF. kFileTypeBIK = 2063, ///< Video, RAD Game Tools Bink. kFileTypeNDB = 2064, ///< Script debugger file. kFileTypePTM = 2065, ///< Plot instance/manager, GFF. kFileTypePTT = 2066, ///< Plot wizard template, GFF. kFileTypeNCM = 2067, kFileTypeMFX = 2068, kFileTypeMAT = 2069, ///< Material. kFileTypeMDB = 2070, ///< Geometry, BioWare model. kFileTypeSAY = 2071, kFileTypeTTF = 2072, ///< Font, True Type. kFileTypeTTC = 2073, kFileTypeCUT = 2074, ///< Cutscene, GFF. kFileTypeKA = 2075, ///< Karma, XML. kFileTypeJPG = 2076, ///< Image, JPEG. kFileTypeICO = 2077, ///< Icon, Windows ICO. kFileTypeOGG = 2078, ///< Audio, Ogg Vorbis. kFileTypeSPT = 2079, ///< Tree data SpeedTree. kFileTypeSPW = 2080, kFileTypeWFX = 2081, ///< Woot effect class, XML. kFileTypeUGM = 2082, kFileTypeQDB = 2083, ///< Quest database, GFF. kFileTypeQST = 2084, ///< Quest, GFF. kFileTypeNPC = 2085, kFileTypeSPN = 2086, kFileTypeUTX = 2087, kFileTypeMMD = 2088, kFileTypeSMM = 2089, kFileTypeUTA = 2090, kFileTypeMDE = 2091, kFileTypeMDV = 2092, kFileTypeMDA = 2093, kFileTypeMBA = 2094, kFileTypeOCT = 2095, kFileTypeBFX = 2096, kFileTypePDB = 2097, kFileTypeTheWitcherSave = 2098, ///< Game save in The Witcher. kFileTypePVS = 2099, kFileTypeCFX = 2100, kFileTypeLUC = 2101, ///< Script, LUA bytecode. kFileTypePRB = 2103, kFileTypeCAM = 2104, ///< Campaign information. kFileTypeVDS = 2105, kFileTypeBIN = 2106, kFileTypeWOB = 2107, kFileTypeAPI = 2108, kFileTypeProperties = 2109, kFileTypePNG = 2110, ///< Image, Portable Network Graphics. kFileTypeLYT = 3000, ///< Area data, room layout. kFileTypeVIS = 3001, ///< Area data, room visibilities. kFileTypeRIM = 3002, ///< Module resources, RIM. kFileTypePTH = 3003, ///< Path finder data, GFF. kFileTypeLIP = 3004, ///< Lipsync data. kFileTypeBWM = 3005, kFileTypeTXB = 3006, ///< Texture. kFileTypeTPC = 3007, ///< Texture. kFileTypeMDX = 3008, ///< Geometry, model mesh data. kFileTypeRSV = 3009, kFileTypeSIG = 3010, kFileTypeMAB = 3011, ///< Material, binary. kFileTypeQST2 = 3012, ///< Quest, GFF. kFileTypeSTO = 3013, ///< GFF. kFileTypeHEX = 3015, ///< Hex grid file. kFileTypeMDX2 = 3016, ///< Geometry, model mesh data. kFileTypeTXB2 = 3017, ///< Texture. kFileTypeFSM = 3022, ///< Finite State Machine data. kFileTypeART = 3023, ///< Area environment settings, INI. kFileTypeAMP = 3024, ///< Brightening control. kFileTypeCWA = 3025, ///< Crowd attributes, GFF. kFileTypeBIP = 3028, ///< Lipsync data, binary LIP. kFileTypeMDB2 = 4000, kFileTypeMDA2 = 4001, kFileTypeSPT2 = 4002, kFileTypeGR2 = 4003, kFileTypeFXA = 4004, kFileTypeFXE = 4005, kFileTypeJPG2 = 4007, kFileTypePWC = 4008, kFileType1DA = 9996, ///< Table data, 1-dimensional text array. kFileTypeERF = 9997, ///< Module resources. kFileTypeBIF = 9998, ///< Game resource data. kFileTypeKEY = 9999, ///< Game resource index. /** The upper limit for numerical type IDs found in archives. */ kFileTypeMAXArchive, /* --- Entries for files not found in archives with numerical type IDs --- */ // Found in NWN kFileTypeEXE = 19000, ///< Windows PE EXE file. kFileTypeDBF = 19001, ///< xBase database. kFileTypeCDX = 19002, ///< FoxPro database index. kFileTypeFPT = 19003, ///< FoxPro database memo file. // Found in NWN2's ZIP files kFileTypeZIP = 20000, ///< Face bone definitions, FaceFX Actor. kFileTypeFXM = 20001, ///< Face metadata, FaceFX. kFileTypeFXS = 20002, ///< Face metadata, FaceFX. kFileTypeXML = 20003, ///< Extensible Markup Language. kFileTypeWLK = 20004, ///< Walk mesh. kFileTypeUTR = 20005, ///< Tree template (user), GFF. kFileTypeSEF = 20006, ///< Special effect file. kFileTypePFX = 20007, ///< Particle effect. kFileTypeTFX = 20008, ///< Trail effect. kFileTypeIFX = 20009, kFileTypeLFX = 20010, ///< Line effect. kFileTypeBBX = 20011, ///< Billboard effect. kFileTypePFB = 20012, ///< Prefab blueprint. kFileTypeUPE = 20013, kFileTypeUSC = 20014, kFileTypeULT = 20015, ///< Light template (user), GFF. kFileTypeFX = 20016, kFileTypeMAX = 20017, kFileTypeDOC = 20018, kFileTypeSCC = 20019, kFileTypeWMP = 20020, ///< World map, GFF. kFileTypeOSC = 20021, kFileTypeTRN = 20022, kFileTypeUEN = 20023, kFileTypeROS = 20024, kFileTypeRST = 20025, kFileTypePTX = 20026, kFileTypeLTX = 20027, kFileTypeTRX = 20028, // Found in Sonic Chronicles: The Dark Brotherhood kFileTypeNDS = 21000, ///< Archive, Nintendo DS ROM file. kFileTypeHERF = 21001, ///< Archive, hashed ERF. kFileTypeDICT = 21002, ///< HERF file name -> hashes dictionary. kFileTypeSMALL = 21003, ///< Compressed file, Nintendo LZSS. kFileTypeCBGT = 21004, kFileTypeCDPTH = 21005, kFileTypeEMIT = 21006, kFileTypeITM = 21007, ///< Items, 2DA. kFileTypeNANR = 21008, ///< Animation, Nitro ANimation Resource. kFileTypeNBFP = 21009, ///< Palette, Nitro Basic File Palette. kFileTypeNBFS = 21010, ///< Image, Map, Nitro Basic File Screen. kFileTypeNCER = 21011, ///< Image, Nitro CEll Resource. kFileTypeNCGR = 21012, ///< Image, Nitro Character Graphic Resource. kFileTypeNCLR = 21013, ///< Palette, Nitro CoLoR. kFileTypeNFTR = 21014, ///< Font. kFileTypeNSBCA = 21015, ///< Model Animation. kFileTypeNSBMD = 21016, ///< Model. kFileTypeNSBTA = 21017, ///< Texture animation. kFileTypeNSBTP = 21018, ///< Texture part. kFileTypeNSBTX = 21019, ///< Texture. kFileTypePAL = 21020, ///< Palette. kFileTypeRAW = 21021, ///< Image, raw. kFileTypeSADL = 21022, kFileTypeSDAT = 21023, ///< Audio, Sound DATa. kFileTypeSMP = 21024, kFileTypeSPL = 21025, ///< Spells, 2DA. kFileTypeVX = 21026, ///< Video, Actimagine. // Found in Dragon Age: Origins kFileTypeANB = 22000, ///< Animation blend. kFileTypeANI = 22001, ///< Animation sequence. kFileTypeCNS = 22002, ///< Script, client script source. kFileTypeCUR = 22003, ///< Cursor, Windows cursor. kFileTypeEVT = 22004, ///< Animation event. kFileTypeFDL = 22005, kFileTypeFXO = 22006, kFileTypeGAD = 22007, ///< GOB Animation Data. kFileTypeGDA = 22008, ///< Table data, GFF'd 2DA, 2-dimensional text array. kFileTypeGFX = 22009, ///< Vector graphics animation, Scaleform GFx. kFileTypeLDF = 22010, ///< Language definition file. kFileTypeLST = 22011, ///< Area list. kFileTypeMAL = 22012, ///< Material Library. kFileTypeMAO = 22013, ///< Material Object. kFileTypeMMH = 22014, ///< Model Mesh Hierarchy. kFileTypeMOP = 22015, kFileTypeMOR = 22016, ///< Head Morph. kFileTypeMSH = 22017, ///< Mesh. kFileTypeMTX = 22018, kFileTypeNCC = 22019, ///< Script, compiled client script. kFileTypePHY = 22020, ///< Physics, Novodex collision info. kFileTypePLO = 22021, ///< Plot information. kFileTypeSTG = 22022, ///< Cutscene stage. kFileTypeTBI = 22023, kFileTypeTNT = 22024, ///< Material tint. kFileTypeARL = 22025, ///< Area layout. kFileTypeFEV = 22026, ///< FMOD Event. kFileTypeFSB = 22027, ///< Audio, FMOD sound bank. kFileTypeOPF = 22028, kFileTypeCRF = 22029, kFileTypeRIMP = 22030, kFileTypeMET = 22031, ///< Resource meta information. kFileTypeMETA = 22032, ///< Resource meta information. kFileTypeFXR = 22033, ///< Face metadata, FaceFX. kFileTypeFXT = 22033, ///< Face metadata, FaceFX. kFileTypeCIF = 22034, ///< Campaign Information File, GFF4. kFileTypeCUB = 22035, kFileTypeDLB = 22036, // Found in KotOR Mac kFileTypeMOV = 23000, ///< Video, QuickTime/MPEG-4. kFileTypeCURS = 23001, ///< Cursor, Mac CURS format. kFileTypePICT = 23002, ///< Image, Mac PICT format. kFileTypeRSRC = 23003, ///< Mac resource fork. kFileTypePLIST = 23004, ///< Mac property list (XML). // Found Jade Empire kFileTypeCRE = 24000, ///< Creature, GFF. kFileTypePSO = 24001, ///< Shader. kFileTypeVSO = 24002, ///< Shader. kFileTypeABC = 24003, ///< Font, character descriptions. kFileTypeSBM = 24004, ///< Font, character bitmap data. kFileTypePVD = 24005, kFileTypePLA = 24006, ///< Placeable, GFF. kFileTypeTRG = 24007, ///< Trigger, GFF. kFileTypePK = 24008, // Found in Dragon Age II kFileTypeALS = 25000, kFileTypeAPL = 25001, kFileTypeAssembly = 25002, kFileTypeBAK = 25003, kFileTypeBNK = 25004, kFileTypeCL = 25005, kFileTypeCNV = 25006, kFileTypeCON = 25007, kFileTypeDAT = 25008, kFileTypeDX11 = 25009, kFileTypeIDS = 25010, kFileTypeLOG = 25011, kFileTypeMAP = 25012, kFileTypeMML = 25013, kFileTypeMP3 = 25014, kFileTypePCK = 25015, kFileTypeRML = 25016, kFileTypeS = 25017, kFileTypeSTA = 25018, kFileTypeSVR = 25019, kFileTypeVLM = 25020, kFileTypeWBD = 25021, kFileTypeXBX = 25022, kFileTypeXLS = 25023, // Found in the iOS version of Knights of the Old Republic kFileTypeBZF = 26000, ///< Game resource data, LZMA-compressed BIF. // Found in The Witcher kFileTypeADV = 27000, ///< Extra adventure modules, ERF. // Our own types kFileTypeXEOSITEX = 40000 ///< Intermediate texture. }; enum GameID { kGameIDUnknown = -1, ///< Unknown game. kGameIDNWN = 0, ///< Neverwinter Nights. kGameIDNWN2 = 1, ///< Neverwinter Nights 2. kGameIDKotOR = 2, ///< Star Wars: Knights of the Old Republic. kGameIDKotOR2 = 3, ///< Star Wars: Knights of the Old Republic II - The Sith Lords. kGameIDJade = 4, ///< Jade Empire. kGameIDWitcher = 5, ///< The Witcher. kGameIDSonic = 6, ///< Sonic Chronicles: The Dark Brotherhood. kGameIDDragonAge = 7, ///< Dragon Age: Origins. kGameIDDragonAge2 = 8, ///< Dragon Age II. kGameIDMAX }; enum ResourceType { kResourceImage, ///< A music resource. kResourceVideo, ///< A video resource. kResourceSound, ///< A sound resource. kResourceMusic, ///< A music resource. kResourceCursor, ///< A cursor resource. kResourceMAX }; enum ArchiveType { kArchiveKEY = 0, ///< KEY archive. kArchiveBIF, ///< BIF archive. kArchiveERF, ///< ERF archive. kArchiveRIM, ///< RIM archive. kArchiveZIP, ///< ZIP archive. kArchiveEXE, ///< EXE archive. kArchiveNDS, ///< Nintendo DS ROM. kArchiveHERF, ///< HERF archive. kArchiveNSBTX, ///< NSBTX texture archives. kArchiveMAX }; enum Platform { kPlatformWindows = 0, ///< Microsoft Windows. kPlatformNDS, ///< Nintendo DS. kPlatformMacOSX, ///< Mac OS X. kPlatformXbox, ///< Microsoft Xbox. kPlatformPS3, ///< Sony PlayStation 3. kPlatformXbox360, ///< Microsoft Xbox 360. kPlatformLinux, ///< GNU/Linux. kPlatformUnknown ///< Unknown (must be last). }; static const uint32 kObjectIDInvalid = 0xFFFFFFFF; static const uint32 kFieldIDInvalid = 0xFFFFFFFF; static const uint32 kStrRefInvalid = 0xFFFFFFFF; class TwoDAFile; class TwoDARow; class GFF3Struct; typedef std::vector GFF3List; class GFF3File; class GFF4Struct; typedef std::vector GFF4List; class GFF4File; } // End of namespace Aurora #endif // AURORA_TYPES_H xoreos-tools-0.0.5/src/aurora/util.cpp000066400000000000000000000434061331663051500177440ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Utility functions to handle files used in BioWare's Aurora engine. */ #include "src/common/util.h" #include "src/common/ustring.h" #include "src/common/filepath.h" #include "src/aurora/util.h" DECLARE_SINGLETON(Aurora::FileTypeManager) namespace Aurora { const FileTypeManager::Type FileTypeManager::types[] = { {kFileTypeNone, "" }, {kFileTypeRES, ".res"}, {kFileTypeBMP, ".bmp"}, {kFileTypeMVE, ".mve"}, {kFileTypeTGA, ".tga"}, {kFileTypeWAV, ".wav"}, {kFileTypePLT, ".plt"}, {kFileTypeINI, ".ini"}, {kFileTypeBMU, ".bmu"}, {kFileTypeMPG, ".mpg"}, {kFileTypeTXT, ".txt"}, {kFileTypeWMA, ".wma"}, {kFileTypeWMV, ".wmv"}, {kFileTypeXMV, ".xmv"}, {kFileTypePLH, ".plh"}, {kFileTypeTEX, ".tex"}, {kFileTypeMDL, ".mdl"}, {kFileTypeTHG, ".thg"}, {kFileTypeFNT, ".fnt"}, {kFileTypeLUA, ".lua"}, {kFileTypeSLT, ".slt"}, {kFileTypeNSS, ".nss"}, {kFileTypeNCS, ".ncs"}, {kFileTypeMOD, ".mod"}, {kFileTypeARE, ".are"}, {kFileTypeSET, ".set"}, {kFileTypeIFO, ".ifo"}, {kFileTypeBIC, ".bic"}, {kFileTypeWOK, ".wok"}, {kFileType2DA, ".2da"}, {kFileTypeTLK, ".tlk"}, {kFileTypeTXI, ".txi"}, {kFileTypeGIT, ".git"}, {kFileTypeBTI, ".bti"}, {kFileTypeUTI, ".uti"}, {kFileTypeBTC, ".btc"}, {kFileTypeUTC, ".utc"}, {kFileTypeDLG, ".dlg"}, {kFileTypeITP, ".itp"}, {kFileTypeBTT, ".btt"}, {kFileTypeUTT, ".utt"}, {kFileTypeDDS, ".dds"}, {kFileTypeBTS, ".bts"}, {kFileTypeUTS, ".uts"}, {kFileTypeLTR, ".ltr"}, {kFileTypeGFF, ".gff"}, {kFileTypeFAC, ".fac"}, {kFileTypeBTE, ".bte"}, {kFileTypeUTE, ".ute"}, {kFileTypeBTD, ".btd"}, {kFileTypeUTD, ".utd"}, {kFileTypeBTP, ".btp"}, {kFileTypeUTP, ".utp"}, {kFileTypeDFT, ".dft"}, {kFileTypeDTF, ".dtf"}, {kFileTypeGIC, ".gic"}, {kFileTypeGUI, ".gui"}, {kFileTypeCSS, ".css"}, {kFileTypeCCS, ".ccs"}, {kFileTypeBTM, ".btm"}, {kFileTypeUTM, ".utm"}, {kFileTypeDWK, ".dwk"}, {kFileTypePWK, ".pwk"}, {kFileTypeBTG, ".btg"}, {kFileTypeUTG, ".utg"}, {kFileTypeJRL, ".jrl"}, {kFileTypeSAV, ".sav"}, {kFileTypeUTW, ".utw"}, {kFileType4PC, ".4pc"}, {kFileTypeSSF, ".ssf"}, {kFileTypeHAK, ".hak"}, {kFileTypeNWM, ".nwm"}, {kFileTypeBIK, ".bik"}, {kFileTypeNDB, ".ndb"}, {kFileTypePTM, ".ptm"}, {kFileTypePTT, ".ptt"}, {kFileTypeNCM, ".ncm"}, {kFileTypeMFX, ".mfx"}, {kFileTypeMAT, ".mat"}, {kFileTypeMDB, ".mdb"}, {kFileTypeSAY, ".say"}, {kFileTypeTTF, ".ttf"}, {kFileTypeTTC, ".ttc"}, {kFileTypeCUT, ".cut"}, {kFileTypeKA, ".ka" }, {kFileTypeJPG, ".jpg"}, {kFileTypeICO, ".ico"}, {kFileTypeOGG, ".ogg"}, {kFileTypeSPT, ".spt"}, {kFileTypeSPW, ".spw"}, {kFileTypeWFX, ".wfx"}, {kFileTypeUGM, ".ugm"}, {kFileTypeQDB, ".qdb"}, {kFileTypeQST, ".qst"}, {kFileTypeNPC, ".npc"}, {kFileTypeSPN, ".spn"}, {kFileTypeUTX, ".utx"}, {kFileTypeMMD, ".mmd"}, {kFileTypeSMM, ".smm"}, {kFileTypeUTA, ".uta"}, {kFileTypeMDE, ".mde"}, {kFileTypeMDV, ".mdv"}, {kFileTypeMDA, ".mda"}, {kFileTypeMBA, ".mba"}, {kFileTypeOCT, ".oct"}, {kFileTypeBFX, ".bfx"}, {kFileTypePDB, ".pdb"}, {kFileTypeTheWitcherSave, ".TheWitcherSave"}, {kFileTypePVS, ".pvs"}, {kFileTypeCFX, ".cfx"}, {kFileTypeLUC, ".luc"}, {kFileTypePRB, ".prb"}, {kFileTypeCAM, ".cam"}, {kFileTypeVDS, ".vds"}, {kFileTypeBIN, ".bin"}, {kFileTypeWOB, ".wob"}, {kFileTypeAPI, ".api"}, {kFileTypeProperties, ".properties"}, {kFileTypePNG, ".png"}, {kFileTypeLYT, ".lyt"}, {kFileTypeVIS, ".vis"}, {kFileTypeRIM, ".rim"}, {kFileTypePTH, ".pth"}, {kFileTypeLIP, ".lip"}, {kFileTypeBWM, ".bwm"}, {kFileTypeTXB, ".txb"}, {kFileTypeTPC, ".tpc"}, {kFileTypeMDX, ".mdx"}, {kFileTypeRSV, ".rsv"}, {kFileTypeSIG, ".sig"}, {kFileTypeMAB, ".mab"}, {kFileTypeQST2, ".qst2"}, {kFileTypeSTO, ".sto"}, {kFileTypeHEX, ".hex"}, {kFileTypeMDX2, ".mdx2"}, {kFileTypeTXB2, ".txb2"}, {kFileTypeFSM, ".fsm"}, {kFileTypeART, ".art"}, {kFileTypeAMP, ".amp"}, {kFileTypeCWA, ".cwa"}, {kFileTypeBIP, ".bip"}, {kFileTypeMDB2, ".mdb2"}, {kFileTypeMDA2, ".mda2"}, {kFileTypeSPT2, ".spt2"}, {kFileTypeGR2, ".gr2"}, {kFileTypeFXA, ".fxa"}, {kFileTypeFXE, ".fxe"}, {kFileTypeJPG2, ".jpg2"}, {kFileTypePWC, ".pwc"}, {kFileType1DA, ".1da"}, {kFileTypeERF, ".erf"}, {kFileTypeBIF, ".bif"}, {kFileTypeKEY, ".key"}, {kFileTypeEXE, ".exe"}, {kFileTypeDBF, ".dbf"}, {kFileTypeCDX, ".cdx"}, {kFileTypeFPT, ".fpt"}, {kFileTypeZIP, ".zip"}, {kFileTypeFXM, ".fxm"}, {kFileTypeFXS, ".fxs"}, {kFileTypeXML, ".xml"}, {kFileTypeWLK, ".wlk"}, {kFileTypeUTR, ".utr"}, {kFileTypeSEF, ".sef"}, {kFileTypePFX, ".pfx"}, {kFileTypeTFX, ".tfx"}, {kFileTypeIFX, ".ifx"}, {kFileTypeLFX, ".lfx"}, {kFileTypeBBX, ".bbx"}, {kFileTypePFB, ".pfb"}, {kFileTypeUPE, ".upe"}, {kFileTypeUSC, ".usc"}, {kFileTypeULT, ".ult"}, {kFileTypeFX , ".fx" }, {kFileTypeMAX, ".max"}, {kFileTypeDOC, ".doc"}, {kFileTypeSCC, ".scc"}, {kFileTypeWMP, ".wmp"}, {kFileTypeOSC, ".osc"}, {kFileTypeTRN, ".trn"}, {kFileTypeUEN, ".uen"}, {kFileTypeROS, ".ros"}, {kFileTypeRST, ".rst"}, {kFileTypePTX, ".ptx"}, {kFileTypeLTX, ".ltx"}, {kFileTypeTRX, ".trx"}, {kFileTypeNDS, ".nds"}, {kFileTypeHERF, ".herf"}, {kFileTypeDICT, ".dict"}, {kFileTypeSMALL, ".small"}, {kFileTypeCBGT, ".cbgt"}, {kFileTypeCDPTH, ".cdpth"}, {kFileTypeEMIT, ".emit"}, {kFileTypeITM, ".itm"}, {kFileTypeNANR, ".nanr"}, {kFileTypeNBFP, ".nbfp"}, {kFileTypeNBFS, ".nbfs"}, {kFileTypeNCER, ".ncer"}, {kFileTypeNCGR, ".ncgr"}, {kFileTypeNCLR, ".nclr"}, {kFileTypeNFTR, ".nftr"}, {kFileTypeNSBCA, ".nsbca"}, {kFileTypeNSBMD, ".nsbmd"}, {kFileTypeNSBTA, ".nsbta"}, {kFileTypeNSBTP, ".nsbtp"}, {kFileTypeNSBTX, ".nsbtx"}, {kFileTypePAL, ".pal"}, {kFileTypeRAW, ".raw"}, {kFileTypeSADL, ".sadl"}, {kFileTypeSDAT, ".sdat"}, {kFileTypeSMP, ".smp"}, {kFileTypeSPL, ".spl"}, {kFileTypeVX, ".vx"}, {kFileTypeANB, ".anb"}, {kFileTypeANI, ".ani"}, {kFileTypeCNS, ".cns"}, {kFileTypeCUR, ".cur"}, {kFileTypeEVT, ".evt"}, {kFileTypeFDL, ".fdl"}, {kFileTypeFXO, ".fxo"}, {kFileTypeGAD, ".gad"}, {kFileTypeGDA, ".gda"}, {kFileTypeGFX, ".gfx"}, {kFileTypeLDF, ".ldf"}, {kFileTypeLST, ".lst"}, {kFileTypeMAL, ".mal"}, {kFileTypeMAO, ".mao"}, {kFileTypeMMH, ".mmh"}, {kFileTypeMOP, ".mop"}, {kFileTypeMOR, ".mor"}, {kFileTypeMSH, ".msh"}, {kFileTypeMTX, ".mtx"}, {kFileTypeNCC, ".ncc"}, {kFileTypePHY, ".phy"}, {kFileTypePLO, ".plo"}, {kFileTypeSTG, ".stg"}, {kFileTypeTBI, ".tbi"}, {kFileTypeTNT, ".tnt"}, {kFileTypeARL, ".arl"}, {kFileTypeFEV, ".fev"}, {kFileTypeFSB, ".fsb"}, {kFileTypeOPF, ".opf"}, {kFileTypeCRF, ".crf"}, {kFileTypeRIMP, ".rimp"}, {kFileTypeMET, ".met"}, {kFileTypeMETA, ".meta"}, {kFileTypeFXR, ".fxr"}, {kFileTypeFXT, ".fxt"}, {kFileTypeCIF, ".cif"}, {kFileTypeCUB, ".cub"}, {kFileTypeDLB, ".dlb"}, {kFileTypeMOV, ".mov"}, {kFileTypeCURS, ".curs"}, {kFileTypePICT, ".pict"}, {kFileTypeRSRC, ".rsrc"}, {kFileTypePLIST, ".plist"}, {kFileTypeCRE, ".cre"}, {kFileTypePSO, ".pso"}, {kFileTypeVSO, ".vso"}, {kFileTypeABC, ".abc"}, {kFileTypeSBM, ".sbm"}, {kFileTypePVD, ".pvd"}, {kFileTypePLA, ".pla"}, {kFileTypeTRG, ".trg"}, {kFileTypePK, ".pk" }, {kFileTypeALS, ".als"}, {kFileTypeAPL, ".apl"}, {kFileTypeAssembly, ".assembly"}, {kFileTypeBAK, ".bak"}, {kFileTypeBNK, ".bnk"}, {kFileTypeCL, ".cl"}, {kFileTypeCNV, ".cnv"}, {kFileTypeCON, ".con"}, {kFileTypeDAT, ".dat"}, {kFileTypeDX11, ".dx11"}, {kFileTypeIDS, ".ids"}, {kFileTypeLOG, ".log"}, {kFileTypeMAP, ".map"}, {kFileTypeMML, ".mml"}, {kFileTypeMP3, ".mp3"}, {kFileTypePCK, ".pck"}, {kFileTypeRML, ".rml"}, {kFileTypeS, ".s" }, {kFileTypeSTA, ".sta"}, {kFileTypeSVR, ".svr"}, {kFileTypeVLM, ".vlm"}, {kFileTypeWBD, ".wbd"}, {kFileTypeXBX, ".xbx"}, {kFileTypeXLS, ".xls"}, {kFileTypeBZF, ".bzf"}, {kFileTypeADV, ".adv"}, {kFileTypeXEOSITEX, ".xoreositex"} }; FileTypeManager::FileTypeManager() { } FileTypeManager::~FileTypeManager() { } FileType FileTypeManager::aliasFileType(FileType type, GameID game) const { // Disambiguate reused type IDs that describe a different file format in a specific game switch (game) { case kGameIDNWN2: switch (type) { case kFileTypeMDB2: return kFileTypeMDB; case kFileTypeMDA2: return kFileTypeMDA; case kFileTypeSPT2: return kFileTypeSPT; case kFileTypeJPG2: return kFileTypeJPG; default: break; } switch (static_cast(type)) { case 3000: return kFileTypeOSC; case 3001: return kFileTypeUSC; case 3002: return kFileTypeTRN; case 3003: return kFileTypeUTR; case 3004: return kFileTypeUEN; case 3005: return kFileTypeULT; case 3006: return kFileTypeSEF; case 3007: return kFileTypePFX; case 3008: return kFileTypeCAM; case 3009: return kFileTypeLFX; case 3010: return kFileTypeBFX; case 3011: return kFileTypeUPE; case 3012: return kFileTypeROS; case 3013: return kFileTypeRST; case 3014: return kFileTypeIFX; case 3015: return kFileTypePFB; case 3016: return kFileTypeZIP; case 3017: return kFileTypeWMP; case 3018: return kFileTypeBBX; case 3019: return kFileTypeTFX; case 3020: return kFileTypeWLK; case 3021: return kFileTypeXML; case 3022: return kFileTypeSCC; case 3033: return kFileTypePTX; case 3034: return kFileTypeLTX; case 3035: return kFileTypeTRX; default: break; } break; case kGameIDJade: switch (type) { case kFileTypeBTC: return kFileTypeCRE; case kFileTypeBTP: return kFileTypePLA; case kFileTypeBTT: return kFileTypeTRG; case kFileTypeGIT: return kFileTypeSAV; case kFileTypeQST2: return kFileTypeQST; case kFileTypeMDX2: return kFileTypeMDX; case kFileTypeTXB2: return kFileTypeTXB; default: break; } break; default: break; } return type; } FileType FileTypeManager::unaliasFileType(FileType type, GameID game) const { switch (game) { case kGameIDNWN2: switch (type) { case kFileTypeOSC: return static_cast(3000); case kFileTypeUSC: return static_cast(3001); case kFileTypeTRN: return static_cast(3002); case kFileTypeUTR: return static_cast(3003); case kFileTypeUEN: return static_cast(3004); case kFileTypeULT: return static_cast(3005); case kFileTypeSEF: return static_cast(3006); case kFileTypePFX: return static_cast(3007); case kFileTypeCAM: return static_cast(3008); case kFileTypeLFX: return static_cast(3009); case kFileTypeBFX: return static_cast(3010); case kFileTypeUPE: return static_cast(3011); case kFileTypeROS: return static_cast(3012); case kFileTypeRST: return static_cast(3013); case kFileTypeIFX: return static_cast(3014); case kFileTypePFB: return static_cast(3015); case kFileTypeZIP: return static_cast(3016); case kFileTypeWMP: return static_cast(3017); case kFileTypeBBX: return static_cast(3018); case kFileTypeTFX: return static_cast(3019); case kFileTypeWLK: return static_cast(3020); case kFileTypeXML: return static_cast(3021); case kFileTypeSCC: return static_cast(3022); case kFileTypePTX: return static_cast(3033); case kFileTypeLTX: return static_cast(3034); case kFileTypeTRX: return static_cast(3035); case kFileTypeMDB: return kFileTypeMDB2; case kFileTypeMDA: return kFileTypeMDA2; case kFileTypeSPT: return kFileTypeSPT2; case kFileTypeJPG: return kFileTypeJPG2; default: break; } break; case kGameIDJade: switch (type) { case kFileTypeCRE: return kFileTypeBTC; case kFileTypePLA: return kFileTypeBTP; case kFileTypeTRG: return kFileTypeBTT; case kFileTypeSAV: return kFileTypeGIT; case kFileTypeQST: return kFileTypeQST2; case kFileTypeMDX: return kFileTypeMDX2; case kFileTypeTXB: return kFileTypeTXB2; default: break; } break; default: break; } return type; } FileType FileTypeManager::getFileType(const Common::UString &path) { buildExtensionLookup(); Common::UString ext = Common::FilePath::getExtension(path).toLower(); ExtensionLookup::const_iterator t = _extensionLookup.find(ext); if (t != _extensionLookup.end()) return t->second->type; return kFileTypeNone; } Common::UString FileTypeManager::addFileType(const Common::UString &path, FileType type) { return setFileType(path + ".", type); } Common::UString FileTypeManager::setFileType(const Common::UString &path, FileType type) { buildTypeLookup(); Common::UString ext; TypeLookup::const_iterator t = _typeLookup.find(type); if (t != _typeLookup.end()) ext = t->second->extension; return Common::FilePath::changeExtension(path, ext); } FileType FileTypeManager::getFileType(Common::HashAlgo algo, uint64 hashedExtension) { if ((algo < 0) || (algo >= Common::kHashMAX)) return kFileTypeNone; buildHashLookup(algo); HashLookup::const_iterator t = _hashLookup[algo].find(hashedExtension); if (t != _hashLookup[algo].end()) return t->second->type; return kFileTypeNone; } void FileTypeManager::buildExtensionLookup() { if (!_extensionLookup.empty()) return; for (size_t i = 0; i < ARRAYSIZE(types); i++) _extensionLookup.insert(std::make_pair(Common::UString(types[i].extension), &types[i])); } void FileTypeManager::buildTypeLookup() { if (!_typeLookup.empty()) return; for (size_t i = 0; i < ARRAYSIZE(types); i++) _typeLookup.insert(std::make_pair(types[i].type, &types[i])); } void FileTypeManager::buildHashLookup(Common::HashAlgo algo) { if (!_hashLookup[algo].empty()) return; for (size_t i = 0; i < ARRAYSIZE(types); i++) { const char *ext = types[i].extension; if (ext[0] == '.') ext++; _hashLookup[algo].insert(std::make_pair(Common::hashString(ext, algo), &types[i])); } } Common::UString getPlatformDescription(Platform platform) { static const char * const names[] = { "Windows", "Nintendo DS", "Mac OS X", "Xbox", "PlayStation 3", "Xbox 360", "GNU/Linux", "Unknown" }; return names[platform]; } } // End of namespace Aurora xoreos-tools-0.0.5/src/aurora/util.h000066400000000000000000000056161331663051500174120ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Utility functions to handle files used in BioWare's Aurora engine. */ #ifndef AURORA_UTIL_H #define AURORA_UTIL_H #include #include "src/common/singleton.h" #include "src/common/hash.h" #include "src/common/ustring.h" #include "src/aurora/types.h" namespace Aurora { /** Return the human readable string of a Platform. */ Common::UString getPlatformDescription(Platform platform); class FileTypeManager : public Common::Singleton { public: FileTypeManager(); ~FileTypeManager(); /** Alias a file type, for reading in original game files. */ FileType aliasFileType(FileType type, GameID game) const; /** Unalias a file type, for writing original game files. */ FileType unaliasFileType(FileType type, GameID game) const; /** Return the file type of a file name, detected by its extension. */ FileType getFileType(const Common::UString &path); /** Return the file type of a file name, detected by its hashed extension. */ FileType getFileType(Common::HashAlgo algo, uint64 hashedExtension); /** Return the file name with an added extensions according to the specified file type. */ Common::UString addFileType(const Common::UString &path, FileType type); /** Return the file name with a swapped extensions according to the specified file type. */ Common::UString setFileType(const Common::UString &path, FileType type); private: /** File type <-> extension mapping. */ struct Type { FileType type; const char *extension; }; static const Type types[]; typedef std::map ExtensionLookup; typedef std::map TypeLookup; typedef std::map HashLookup; ExtensionLookup _extensionLookup; TypeLookup _typeLookup; HashLookup _hashLookup[Common::kHashMAX]; void buildExtensionLookup(); void buildTypeLookup(); void buildHashLookup(Common::HashAlgo algo); }; } // End of namespace Aurora /** Shortcut for accessing the file type manager. */ #define TypeMan ::Aurora::FileTypeManager::instance() #endif // AURORA_UTIL_H xoreos-tools-0.0.5/src/cbgt2tga.cpp000066400000000000000000000065471331663051500172000ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Tool to convert CBGT images to TGA. */ #include #include #include #include "src/version/version.h" #include "src/common/ustring.h" #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/error.h" #include "src/common/platform.h" #include "src/common/readfile.h" #include "src/common/cli.h" #include "src/aurora/types.h" #include "src/aurora/util.h" #include "src/images/cbgt.h" #include "src/util.h" bool parseCommandLine(const std::vector &argv, int &returnValue, Common::UString &cbgtFile , Common::UString &palFile, Common::UString &twoDAFile, Common::UString &outFile); void convert(const Common::UString &cbgtFile , const Common::UString &palFile, const Common::UString &twoDAFile, const Common::UString &outFile); int main(int argc, char **argv) { initPlatform(); try { std::vector args; Common::Platform::getParameters(argc, argv, args); int returnValue = 1; Common::UString cbgtFile, palFile, twoDAFile, outFile; if (!parseCommandLine(args, returnValue, cbgtFile, palFile, twoDAFile, outFile)) return returnValue; convert(cbgtFile, palFile, twoDAFile, outFile); } catch (...) { Common::exceptionDispatcherError(); } return 0; } bool parseCommandLine(const std::vector &argv, int &returnValue, Common::UString &cbgtFile , Common::UString &palFile, Common::UString &twoDAFile, Common::UString &outFile) { using Common::CLI::Parser; using Common::CLI::ValGetter; using Common::CLI::NoOption; using Common::CLI::makeEndArgs; std::vector getters; NoOption cbgtFileOpt(false, new ValGetter(cbgtFile, "cbgt")); NoOption palFileOpt(false, new ValGetter(palFile, "pal")); NoOption twoDAFileOpt(false, new ValGetter(twoDAFile, "2da")); NoOption outFileOpt(false, new ValGetter(outFile, "tga")); Parser parser(argv[0], "CBGT image to TGA converter", "", returnValue, makeEndArgs(&cbgtFileOpt, &palFileOpt, &twoDAFileOpt, &outFileOpt)); return parser.process(argv); } void convert(const Common::UString &cbgtFile , const Common::UString &palFile, const Common::UString &twoDAFile, const Common::UString &outFile) { Common::ReadFile cbgt(cbgtFile), pal(palFile), twoDA(twoDAFile); Images::CBGT image(cbgt, pal, twoDA); image.flipVertically(); image.dumpTGA(outFile); } xoreos-tools-0.0.5/src/cdpth2tga.cpp000066400000000000000000000067341331663051500173610ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Tool to convert CDPTH depth images to TGA. */ #include #include #include #include "src/version/version.h" #include "src/common/ustring.h" #include "src/common/util.h" #include "src/common/strutil.h" #include "src/common/error.h" #include "src/common/platform.h" #include "src/common/readfile.h" #include "src/common/cli.h" #include "src/aurora/types.h" #include "src/aurora/util.h" #include "src/aurora/2dafile.h" #include "src/images/cdpth.h" #include "src/util.h" bool parseCommandLine(const std::vector &argv, int &returnValue, Common::UString &cdpthFile, Common::UString &twoDAFile, Common::UString &outFile); void convert(const Common::UString &cdpthFile, const Common::UString &twoDAFile, const Common::UString &outFile); int main(int argc, char **argv) { initPlatform(); try { std::vector args; Common::Platform::getParameters(argc, argv, args); int returnValue = 1; Common::UString cdpthFile, twoDAFile, outFile; if (!parseCommandLine(args, returnValue, cdpthFile, twoDAFile, outFile)) return returnValue; convert(cdpthFile, twoDAFile, outFile); } catch (...) { Common::exceptionDispatcherError(); } return 0; } bool parseCommandLine(const std::vector &argv, int &returnValue, Common::UString &cdpthFile, Common::UString &twoDAFile, Common::UString &outFile) { using Common::CLI::Parser; using Common::CLI::ValGetter; using Common::CLI::NoOption; using Common::CLI::makeEndArgs; std::vector getters; NoOption cdpthFileOpt(false, new ValGetter(cdpthFile, "cdpth")); NoOption twoDAFileOpt(false, new ValGetter(twoDAFile, "2da")); NoOption outFileOpt(false, new ValGetter(outFile, "tga")); Parser parser(argv[0], "CDPTH depth image to TGA converter", "", returnValue, makeEndArgs(&cdpthFileOpt, &twoDAFileOpt, &outFileOpt)); return parser.process(argv); } static void getDimensions(const Common::UString &twoDAFile, uint32 &width, uint32 &height) { Common::ReadFile twoDAStream(twoDAFile); Aurora::TwoDAFile twoDA(twoDAStream); width = twoDA.getColumnCount() * 64; height = twoDA.getRowCount() * 64; } void convert(const Common::UString &cdpthFile, const Common::UString &twoDAFile, const Common::UString &outFile) { uint32 width, height; getDimensions(twoDAFile, width, height); Common::ReadFile cdpth(cdpthFile); Images::CDPTH image(cdpth, width, height); image.flipVertically(); image.dumpTGA(outFile); } xoreos-tools-0.0.5/src/common/000077500000000000000000000000001331663051500162535ustar00rootroot00000000000000xoreos-tools-0.0.5/src/common/base64.cpp000066400000000000000000000156021331663051500200470ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Base64 encoding and decoding. */ #include #include "src/common/base64.h" #include "src/common/scopedptr.h" #include "src/common/ustring.h" #include "src/common/error.h" #include "src/common/readstream.h" #include "src/common/memreadstream.h" #include "src/common/memwritestream.h" namespace Common { static const char kBase64Char[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const uint8 kBase64Values[128] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /** Write a character into our base64 string, and update the remaining * string length. * * Returns false if we ran out of remaining characters in this string. */ static bool writeCharacter(UString &base64, uint32 c, size_t &maxLength) { assert(maxLength > 0); base64 += c; return --maxLength > 0; } /** Write multiple characters into our base64 string, and update the remaining * string length. * * Returns false if we ran out of remaining characters in this string. */ static bool writeCharacters(UString &base64, UString &str, size_t &lineLength) { while (!str.empty()) { writeCharacter(base64, *str.begin(), lineLength); str.erase(str.begin()); if (lineLength == 0) return false; } return lineLength > 0; } /** Find the raw value of a base64-encoded character. */ static uint8 findCharacterValue(uint32 c) { if ((c >= 128) || (kBase64Values[c] > 0x3F)) throw Exception("Invalid base64 character"); return kBase64Values[c]; } /** Encode data into base64 and write the result into the string, but only up * to maxLength characters. * * The string overhang is and input/output string of both the overhang from * the previous run of this function (which will get written into the base64 * string first) and the newly produced overhang. * * Returns false if we have written all data there is to write, both from the * overhang and the input data stream. */ static bool encodeBase64(ReadStream &data, UString &base64, size_t maxLength, UString &overhang) { if (maxLength == 0) throw Exception("Invalid base64 max line length"); // First write the overhang, and return if we already maxed out the length there if (!writeCharacters(base64, overhang, maxLength)) return true; overhang.clear(); uint8 n; byte input[3]; // Read up to 3 characters at a time while ((n = data.read(input, 3)) != 0) { uint32 code = 0; // Concat the input characters for (uint8 i = 0; i < n; i++) code |= input[i] << (24 - i * 8); // Create up to 4 6-bit base64-characters out of them for (uint8 i = 0; i < (n + 1); i++) { overhang += kBase64Char[(code >> 26) & 0x0000003F]; code <<= 6; } // Add padding for (int i = 0; i < (3 - n); i++) overhang += '='; // Write the base64 characters into the string, and return if we maxed out the length if (!writeCharacters(base64, overhang, maxLength)) return true; overhang.clear(); } // We reached the end of input the data return false; } static void decodeBase64(WriteStream &data, const UString &base64, UString &overhang) { assert(overhang.size() < 4); for (UString::iterator c = base64.begin(); c != base64.end(); ++c) { overhang += *c; if (overhang.size() == 4) { uint32 code = 0; uint8 n = 0; for (UString::iterator o = overhang.begin(); o != overhang.end(); ++o) { code <<= 6; if (*o != '=') { code += findCharacterValue(*o); n += 6; } } for (size_t i = 0; i < (n / 8); i++, code <<= 8) data.writeByte((byte) ((code & 0x00FF0000) >> 16)); overhang.clear(); } } } static size_t countLength(const UString &str) { const size_t dataLength = str.size(); if ((dataLength % 4) != 0) throw Exception("Invalid length for a base64-encoded string"); return dataLength; } static size_t countLength(const std::list &str) { size_t dataLength = 0; for (std::list::const_iterator s = str.begin(); s != str.end(); ++s) dataLength += s->size(); if ((dataLength % 4) != 0) throw Exception("Invalid length for a base64-encoded string"); return dataLength; } void encodeBase64(ReadStream &data, UString &base64) { UString overhang; encodeBase64(data, base64, SIZE_MAX, overhang); } void encodeBase64(ReadStream &data, std::list &base64, size_t lineLength) { UString overhang; // Base64-encode the data, creating a new string after every lineLength characters do { base64.push_back(UString()); } while (encodeBase64(data, base64.back(), lineLength, overhang)); // Trim empty strings from the back while (!base64.empty() && base64.back().empty()) base64.pop_back(); } SeekableReadStream *decodeBase64(const UString &base64) { const size_t dataLength = (countLength(base64) / 4) * 3; ScopedArray data(new byte[dataLength]); MemoryWriteStream output(data.get(), dataLength); UString overhang; decodeBase64(output, base64, overhang); return new MemoryReadStream(data.release(), output.pos(), true); } SeekableReadStream *decodeBase64(const std::list &base64) { const size_t dataLength = (countLength(base64) / 4) * 3; ScopedArray data(new byte[dataLength]); MemoryWriteStream output(data.get(), dataLength); UString overhang; for (std::list::const_iterator b = base64.begin(); b != base64.end(); ++b) decodeBase64(output, *b, overhang); return new MemoryReadStream(data.release(), output.pos(), true); } } // End of namespace Common xoreos-tools-0.0.5/src/common/base64.h000066400000000000000000000044721331663051500175170ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Base64 encoding and decoding. * * Base64 encodes binary data into printable ASCII, by representing data in * in radix 64. It maps each 3 input bytes onto 4 printable characters. * * This implements the most commonly found Base64 variant, as also used by, * for example, MIME. It uses, in order, the 26 uppercase Latin letters (A-Z), * the 26 lowercase Latin letters (a-z), the 10 Hindu-Arabic digits (0-9), * the plus symbol (+) and the forward slash (/). When the input length is * *not* divisible by 3, and therefore less than 4 output characters would be * generated, the output is padded with one or two equal signs (=). */ #ifndef COMMON_BASE64_H #define COMMON_BASE64_H #include #include "src/common/types.h" namespace Common { class UString; class ReadStream; class SeekableReadStream; /** Encode the binary stream data into a Base64 string. */ void encodeBase64(ReadStream &data, UString &base64); /** Encode the binary stream data into a list of Base64 strings of at max lineLength characters. */ void encodeBase64(ReadStream &data, std::list &base64, size_t lineLength); /** Decode the Base64 string into binary data, returning a newly allocated stream. */ SeekableReadStream *decodeBase64(const UString &base64); /** Decode the list of Base64 strings into binary data, returning a newly allocated stream. */ SeekableReadStream *decodeBase64(const std::list &base64); } // End of namespace Common #endif // COMMON_BASE64_H xoreos-tools-0.0.5/src/common/binsearch.h000066400000000000000000000033571331663051500203720ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Simple utility template for searching through static const maps. */ #ifndef COMMON_BINSEARCH_H #define COMMON_BINSEARCH_H #include namespace Common { /** Struct template for a generic searchable key/value pair. */ template struct BinSearchValue { TK key; TV value; }; /** Search through this sorted list of key/value pairs. */ template const BinSearchValue *binarySearch(const BinSearchValue *map, size_t size, const TK &value) { size_t low = 0, high = size - 1, midpoint = 0; while ((low <= high) && (high < size) && (low < size)) { midpoint = low + ((high - low) / 2); if (value == map[midpoint].key) return &map[midpoint]; else if (value < map[midpoint].key) high = midpoint - 1; else low = midpoint + 1; } return 0; } } // End of namespace Common #endif // COMMON_BINSEARCH_H xoreos-tools-0.0.5/src/common/blowfish.cpp000066400000000000000000000460341331663051500206030ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Encryption / decryption using Bruce Schneier's Blowfish algorithm. */ #include #include "src/common/util.h" #include "src/common/error.h" #include "src/common/scopedptr.h" #include "src/common/memreadstream.h" #include "src/common/blowfish.h" namespace Common { /* .--- Blowfish, based on the implementation from mbed TLS ---. * * This is an implementation of Bruce Schneier's Blowfish algorithm based on * the implementation found in the mbed TLS library (), * licensed under the terms of the Apache License, Version 2.0. * * The original copyright note in blowfish.c reads as follows: * * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file is part of mbed TLS (https://tls.mbed.org) * * The Blowfish block cipher was designed by Bruce Schneier in 1993. * http://www.schneier.com/blowfish.html * http://en.wikipedia.org/wiki/Blowfish_%28cipher%29 */ enum Mode { kModeDecrypt = 0, kModeEncrypt = 1 }; static const size_t kMinKeyLength = 4; static const size_t kMaxKeyLength = 56; static const size_t kRoundCount = 16; static const size_t kBlockSize = 8; struct BlowfishContext { uint32 P[kRoundCount + 2]; ///< Blowfish round keys. uint32 S[4][256]; ///< Key-dependant S-boxes. BlowfishContext() { std::memset(P, 0, sizeof(P)); std::memset(S, 0, sizeof(S)); } ~BlowfishContext() { /* We don't care about security here, so we do *not* zeroize the buffers. * Residuals of the encryption/decryption *will* be left in memory! * * WARNING: DO NOT USE THIS CODE IN SECURITY RELEVANT SITUATIONS! */ } }; static const uint32 P[kRoundCount + 2] = { 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B }; static const uint32 S[4][256] = { { 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A }, { 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 }, { 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 }, { 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 } }; static uint32 F(const BlowfishContext &ctx, uint32 x) { const uint16 d = (uint16)(x & 0xFF); x >>= 8; const uint16 c = (uint16)(x & 0xFF); x >>= 8; const uint16 b = (uint16)(x & 0xFF); x >>= 8; const uint16 a = (uint16)(x & 0xFF); return ((ctx.S[0][a] + ctx.S[1][b]) ^ ctx.S[2][c]) + ctx.S[3][d]; } static void blowfishEnc(BlowfishContext &ctx, uint32 &xl, uint32 &xr) { for (size_t i = 0; i < kRoundCount; i++) { xl = xl ^ ctx.P[i]; xr = F(ctx, xl) ^ xr; SWAP(xl, xr); } SWAP(xl, xr); xr = xr ^ ctx.P[kRoundCount]; xl = xl ^ ctx.P[kRoundCount + 1]; } static void blowfishDec(BlowfishContext &ctx, uint32 &xl, uint32 &xr) { for (size_t i = kRoundCount + 1; i > 1; i--) { xl = xl ^ ctx.P[i]; xr = F(ctx, xl) ^ xr; SWAP(xl, xr); } SWAP(xl, xr); xr = xr ^ ctx.P[1]; xl = xl ^ ctx.P[0]; } static void blowfishSetKey(BlowfishContext &ctx, const byte *key, size_t keyLength) { if ((keyLength < kMinKeyLength) || (keyLength > kMaxKeyLength)) throw Exception("Invalid Blowfish key length %u", (uint) keyLength); for (size_t i = 0; i < 4; i++) { for (size_t j = 0; j < 256; j++) ctx.S[i][j] = S[i][j]; } size_t k = 0; for (size_t i = 0; i < kRoundCount + 2; i++) { uint32 data = 0x00000000; for (size_t j = 0; j < 4; j++) { data = (data << 8) | key[k++]; if (k >= keyLength) k = 0; } ctx.P[i] = P[i] ^ data; } uint32 dataL = 0x00000000; uint32 dataR = 0x00000000; for (size_t i = 0; i < kRoundCount + 2; i += 2) { blowfishEnc(ctx, dataL, dataR); ctx.P[i ] = dataL; ctx.P[i + 1] = dataR; } for (size_t i = 0; i < 4; i++) { for (size_t j = 0; j < 256; j += 2) { blowfishEnc(ctx, dataL, dataR); ctx.S[i][j ] = dataL; ctx.S[i][j + 1] = dataR; } } } static void blowfishECB(BlowfishContext &ctx, Mode mode, const byte *input, byte *output) { uint32 X0 = READ_BE_UINT32(input); uint32 X1 = READ_BE_UINT32(input + 4); switch (mode) { case kModeDecrypt: blowfishDec(ctx, X0, X1); break; case kModeEncrypt: blowfishEnc(ctx, X0, X1); break; default: assert(false); } WRITE_BE_UINT32(output , X0); WRITE_BE_UINT32(output + 4, X1); } // '--- Blowfish, based on the implementation from mbed TLS ---' MemoryReadStream *blowfishEBC(SeekableReadStream &input, const std::vector &key, Mode mode) { BlowfishContext ctx; blowfishSetKey(ctx, &key[0], key.size()); size_t inputSize = input.size() - input.pos(); // Round up to the next multiple of the block size const size_t outputSize = ((inputSize + kBlockSize - 1) / kBlockSize) * kBlockSize; ScopedArray output(new byte[outputSize]); byte buffer[kBlockSize]; byte *data = output.get(); while (inputSize > 0) { const size_t toRead = MIN(inputSize, kBlockSize); if (input.read(buffer, toRead) != toRead) throw Exception(kReadError); if (toRead < kBlockSize) std::memset(buffer + toRead, 0, kBlockSize - toRead); blowfishECB(ctx, mode, buffer, data); data += toRead; inputSize -= toRead; } return new MemoryReadStream(output.release(), outputSize, true); } MemoryReadStream *encryptBlowfishEBC(SeekableReadStream &input, const std::vector &key) { return blowfishEBC(input, key, kModeEncrypt); } MemoryReadStream *decryptBlowfishEBC(SeekableReadStream &input, const std::vector &key) { if ((input.size() % 8) != 0) throw Exception("Blowfish operates on blocks of 8 bytes (%u)", (uint) input.size()); return blowfishEBC(input, key, kModeDecrypt); } } // End of namespace Common xoreos-tools-0.0.5/src/common/blowfish.h000066400000000000000000000027411331663051500202450ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ /** @file * Encryption / decryption using Bruce Schneier's Blowfish algorithm. */ #ifndef COMMON_BLOWFISH_H #define COMMON_BLOWFISH_H #include #include "src/common/types.h" namespace Common { class SeekableReadStream; class MemoryReadStream; /** Encrypt the stream with the Blowfish algorithm in EBC mode. */ MemoryReadStream *encryptBlowfishEBC(SeekableReadStream &input, const std::vector &key); /** Decrypt the stream with the Blowfish algorithm in EBC mode. */ MemoryReadStream *decryptBlowfishEBC(SeekableReadStream &input, const std::vector &key); } // End of namespace Common #endif // COMMON_BLOWFISH_H xoreos-tools-0.0.5/src/common/cli.cpp000066400000000000000000000211661331663051500175340ustar00rootroot00000000000000/* xoreos-tools - Tools to help with xoreos development * * xoreos-tools is the legal property of its developers, whose names * can be found in the AUTHORS file distributed with this source * distribution. * * xoreos-tools is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * xoreos-tools is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with xoreos-tools. If not, see . */ #include #include #include #include "src/version/version.h" #include "src/common/cli.h" namespace Common { namespace CLI { static void cliSetHelp(UString &helpStr, const char *longName, char shortName, const char *optionArgs, uint32_t maxArgLength, const char *help) { helpStr += " "; if (shortName) { helpStr += '-'; helpStr += shortName; } else { helpStr += " "; } helpStr += " --"; helpStr += longName; helpStr += " "; helpStr += optionArgs; for (int i = (maxArgLength - strlen(longName) - strlen(optionArgs) - 4); i > 0; --i) { helpStr += " "; } if (help) { helpStr += help; } helpStr += "\n"; } template<> int ValGetter::get(const std::vector &args, int i, int) { _val = args[i]; return 0; } template<> int ValGetter::get(const std::vector &args, int i, int) { const char *str = args[i].c_str(); for (int j = 0;j < str[j]; ++j) { if (!UString::isDigit(str[j])) return -1; } _val = atoi(str); return 0; } template<> int ValGetter::get(const std::vector &args, int i, int) { const char *str = args[i].c_str(); int j = 0; if (str[0] == '-') ++j; for (;j < str[j]; ++j) { if (!UString::isDigit(str[j])) return -1; } _val = atoi(str); return 0; } template<> int ValGetter &>::get(const std::vector &args, int i, int size) { int j = i; for (; j < size; ++j) _val.push_back(args[j]); return j - i; } template<> int ValGetter &>::get(const std::vector &args, int i, int size) { int j = i; for (; j < size; ++j) _val.push_back(args[j]); return j - i; } template<> int ValGetter &>::get(const std::vector &args, int i, int size) { int j = i; for (; j < size; ++j) _val.insert(args[j]); return j - i; } int Option::doOption(const std::vector &args, int i, int size) { switch (_type) { case kAssigner: assign(); break; case kPrinter: if (this->_printer.print()) { _printer.print()(_printer.printerStr()); } else { _printer.vPrint()(); } break; case kCallback: if (i + 1 < size) _callback->process(args[i + 1]); return 1; case kGetter: if (i + 1 < size) return _getter->get(args, i + 1, size) + 1; break; default: break; } return 0; } void Option::assign() { for (int i = 0, end = _assigners.size(); i < end; ++i) _assigners[i]->assign(); } void Option::free() { switch (_type) { case kGetter: delete _getter; break; case kCallback: delete _callback; break; case kAssigner: for (int i = 0, end = _assigners.size(); i < end; ++i) delete _assigners[i]; break; default: break; } } void NoOption::free() { delete _getter; } Parser::Parser(const UString &name, const char *description, const char *bottom, int &returnVal, std::vector endCli) : _bottom(bottom), _helpStr(description), _options(), _noOptions(endCli), _returnVal(returnVal) { _helpStr += "\n\nUsage: "; _helpStr += name; _helpStr += " []"; for (unsigned int i = 0; i < endCli.size(); ++i) { if (!endCli[i].isOptional()) { _helpStr += " <"; _helpStr += endCli[i].getter()->name(); _helpStr += ">"; } else { _helpStr += " ["; _helpStr += endCli[i].getter()->name(); _helpStr += "]"; } } _helpStr += "\n\n"; this->addOption("help", 'h', "This help text", kEndSucess, printUsage, _helpStr); this->addOption("version", 0, "Display version information", kEndSucess, Version::printVersion); } Parser::~Parser() { for (int i = 0, end = _options.size(); i < end; ++i) { if (_options[i]) _options[i]->free(); delete _options[i]; } for (int i = 0, end = _noOptions.size(); i < end; ++i) { _noOptions[i].free(); } } void Parser::addOption(const char *longName, char shortName, const char *help, OptionRet ret, void (*printer)()) { _options.push_back(new Option(longName, shortName, help, ret, printer)); } void Parser::addOption(const char *longName, char shortName, const char *help, OptionRet ret, void (*printer)(UString &), UString &str) { _options.push_back(new Option(longName, shortName, help, ret, printer, str)); } void Parser::addOption(const char *longName, char shortName, const char *help, OptionRet ret, std::vector assigners) { _options.push_back(new Option(longName, shortName, help, ret, assigners)); } void Parser::addOption(const char *longName, char shortName, const char *help, OptionRet ret, Getter *getter) { _options.push_back(new Option(longName, shortName, help, ret, getter)); } void Parser::addOption(const char *longName, char shortName, const char *help, OptionRet ret, CallbackBase *callback) { _options.push_back(new Option(longName, shortName, help, ret, callback)); } Option *findMatchOptionShortName(std::vector