aboutsummaryrefslogtreecommitdiff
path: root/games/xray_re-tools
diff options
context:
space:
mode:
authorAlexey Dokuchaev <danfe@FreeBSD.org>2019-02-22 14:46:50 +0000
committerAlexey Dokuchaev <danfe@FreeBSD.org>2019-02-22 14:46:50 +0000
commit9d0ffa942164a7127b30e78e03b472bf54447648 (patch)
treebb46960aee0ba55b71e9ed00cc76f65d0867e62b /games/xray_re-tools
parent09c43cff9f764408e510d2e4e48cdb486e0ceb90 (diff)
downloadports-9d0ffa942164a7127b30e78e03b472bf54447648.tar.gz
ports-9d0ffa942164a7127b30e78e03b472bf54447648.zip
Portable (POSIX) subset of the X-Ray unofficial toolset used for modding the
S.T.A.L.K.E.R. game series by GSC Game World. Currently includes standalone converter utility which is useful for casual gamers to unpack game resources. I've ported it back in 2012 but never committed for some reason. WWW: https://github.com/abramcumner/xray_re-tools
Notes
Notes: svn path=/head/; revision=493572
Diffstat (limited to 'games/xray_re-tools')
-rw-r--r--games/xray_re-tools/Makefile60
-rw-r--r--games/xray_re-tools/distinfo3
-rw-r--r--games/xray_re-tools/files/Makefile170
-rw-r--r--games/xray_re-tools/files/patch-sources_3rd-party_nvtt_nvcore_Memory.h20
-rw-r--r--games/xray_re-tools/files/patch-sources_3rd-party_nvtt_nvcore_poshlib_posh.h14
-rw-r--r--games/xray_re-tools/files/patch-sources_utils_converter_db__tools.cxx63
-rw-r--r--games/xray_re-tools/files/patch-sources_utils_converter_dds__tools.cxx42
-rw-r--r--games/xray_re-tools/files/patch-sources_utils_converter_ogg__tools.cxx43
-rw-r--r--games/xray_re-tools/files/patch-sources_utils_converter_opcode_Ice_IceTypes.h17
-rw-r--r--games/xray_re-tools/files/patch-sources_utils_converter_opcode_Opcode.h22
-rw-r--r--games/xray_re-tools/files/patch-sources_xray__re_xr__file__system.cxx27
-rw-r--r--games/xray_re-tools/files/patch-sources_xray__re_xr__file__system__posix.cxx291
-rw-r--r--games/xray_re-tools/files/patch-sources_xray__re_xr__file__system__posix.h32
-rw-r--r--games/xray_re-tools/files/patch-sources_xray__re_xr__writer.cxx11
-rw-r--r--games/xray_re-tools/files/patch-sources_xray__re_xr__writer.h14
-rw-r--r--games/xray_re-tools/pkg-descr11
16 files changed, 840 insertions, 0 deletions
diff --git a/games/xray_re-tools/Makefile b/games/xray_re-tools/Makefile
new file mode 100644
index 000000000000..591d50aef548
--- /dev/null
+++ b/games/xray_re-tools/Makefile
@@ -0,0 +1,60 @@
+# Created by: Alexey Dokuchaev <danfe@FreeBSD.org>
+# $FreeBSD$
+
+PORTNAME= xray_re-tools
+DISTVERSION= g20180902
+CATEGORIES= games converters
+
+MAINTAINER= danfe@FreeBSD.org
+COMMENT= X-Ray engine assets converter (unofficial)
+
+LIB_DEPENDS= liblzo2.so:archivers/lzo2 \
+ libvorbisfile.so:audio/libvorbis \
+ libnvtt.so:graphics/nvidia-texture-tools
+
+USE_GITHUB= yes
+GH_ACCOUNT= abramcumner
+GH_TAGNAME= 52721d2
+
+MAKEFILE= ${FILESDIR}/Makefile
+BUILD_WRKSRC= ${WRKSRC}/sources
+WITHOUT_FBSD10_FIX= yes
+
+PLIST_FILES= bin/xr_converter
+
+post-extract:
+ @${MV} ${WRKSRC}/sources/3rd\ party ${WRKSRC}/sources/3rd-party
+ @${MV} ${WRKSRC}/sources/utils/converter/opcode/Ice/IceTrilist.h \
+ ${WRKSRC}/sources/utils/converter/opcode/Ice/IceTriList.h
+ @${LN} -s StdAfx.h ${WRKSRC}/sources/utils/converter/opcode/Stdafx.h
+
+post-patch:
+ @${REINPLACE_CMD} -e '/#include/s,Math,math,' \
+ -e '/#include/s,\.\\Ice\\,Ice/,' \
+ ${WRKSRC}/sources/utils/converter/opcode/OPC_IceHook.h
+ @${REINPLACE_CMD} -e 's,string& version,string version,' \
+ ${WRKSRC}/sources/utils/converter/level_tools.cxx
+ @${REINPLACE_CMD} -e 's,push_back,this->&,' \
+ ${WRKSRC}/sources/xray_re/xr_influence.h
+ @${REINPLACE_CMD} -e 's,type_info& type,std::&,' \
+ ${WRKSRC}/sources/xray_re/xr_scene.cxx
+ @${REINPLACE_CMD} -e 's,sprintf_s,xr_snprintf,' \
+ ${WRKSRC}/sources/xray_re/xr_scene_ways.cxx
+ @${REINPLACE_CMD} -e '/return/s,_stricmp,strcasecmp,' \
+ ${WRKSRC}/sources/xray_re/xr_string_utils.h
+ @${REINPLACE_CMD} -e 's,MINGW32__),& || defined(__FreeBSD__),' \
+ ${WRKSRC}/sources/xray_re/xr_types.h
+
+do-install:
+ ${INSTALL_PROGRAM} ${BUILD_WRKSRC}/converter \
+ ${STAGEDIR}${PREFIX}/bin/xr_converter
+
+# Alternative to DOS2UNIX_FILES that preserves original timestamps,
+# to be used together with `-l' switch added to PATCH_ARGS below.
+fixpatches:
+ ${FIND} ${FILESDIR} -name patch-* | ${XARGS} ${SED} -i '' \
+ -E 's,[[:cntrl:]]*$$,,'
+
+.include <bsd.port.mk>
+
+PATCH_ARGS+= -l
diff --git a/games/xray_re-tools/distinfo b/games/xray_re-tools/distinfo
new file mode 100644
index 000000000000..5206f0237c57
--- /dev/null
+++ b/games/xray_re-tools/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1535892164
+SHA256 (abramcumner-xray_re-tools-g20180902-52721d2_GH0.tar.gz) = 6ba187e25e57ff64937632f524d5307fcfdbb6cd1eca1e34331eb7eb6fd25238
+SIZE (abramcumner-xray_re-tools-g20180902-52721d2_GH0.tar.gz) = 4555551
diff --git a/games/xray_re-tools/files/Makefile b/games/xray_re-tools/files/Makefile
new file mode 100644
index 000000000000..3220d663a3ba
--- /dev/null
+++ b/games/xray_re-tools/files/Makefile
@@ -0,0 +1,170 @@
+CXXFLAGS+= -Wall -Wextra
+CPPFLAGS+= -Ixray_re -Iutils/converter/opcode -I3rd-party/nvtt -I$(LOCALBASE)/include
+LDFLAGS+= -L$(LOCALBASE)/lib
+
+xray_re_OBJS= xray_re/xr_ai_cross_table.o \
+ xray_re/xr_ai_graph.o \
+ xray_re/xr_ai_way.o \
+ xray_re/xr_blender.o \
+ xray_re/xr_bone.o \
+ xray_re/xr_build_err.o \
+ xray_re/xr_build_lights.o \
+ xray_re/xr_cform.o \
+ xray_re/xr_cl_parser.o \
+ xray_re/xr_clsid.o \
+ xray_re/xr_d3d_light.o \
+ xray_re/xr_details.o \
+ xray_re/xr_dm.o \
+ xray_re/xr_entity.o \
+ xray_re/xr_entity_factory.o \
+ xray_re/xr_entity_la.o \
+ xray_re/xr_entity_script.o \
+ xray_re/xr_entity_zenobian.o \
+ xray_re/xr_envelope.o \
+ xray_re/xr_envelope_eval.o \
+ xray_re/xr_file_system.o \
+ xray_re/xr_file_system_posix.o \
+ xray_re/xr_game_graph.o \
+ xray_re/xr_game_spawn.o \
+ xray_re/xr_gamemtls_lib.o \
+ xray_re/xr_geom_buf.o \
+ xray_re/xr_guid.o \
+ xray_re/xr_image.o \
+ xray_re/xr_image_bmp.o \
+ xray_re/xr_image_dds.o \
+ xray_re/xr_image_tga.o \
+ xray_re/xr_influence.o \
+ xray_re/xr_ini_file.o \
+ xray_re/xr_level.o \
+ xray_re/xr_level_ai.o \
+ xray_re/xr_level_cform.o \
+ xray_re/xr_level_details.o \
+ xray_re/xr_level_dm.o \
+ xray_re/xr_level_env_mod.o \
+ xray_re/xr_level_fog_vol.o \
+ xray_re/xr_level_game.o \
+ xray_re/xr_level_gct.o \
+ xray_re/xr_level_gct_v9.o \
+ xray_re/xr_level_geom.o \
+ xray_re/xr_level_glows.o \
+ xray_re/xr_level_graph.o \
+ xray_re/xr_level_hom.o \
+ xray_re/xr_level_lights.o \
+ xray_re/xr_level_ltx.o \
+ xray_re/xr_level_portals.o \
+ xray_re/xr_level_ps_static.o \
+ xray_re/xr_level_sectors.o \
+ xray_re/xr_level_shaders.o \
+ xray_re/xr_level_snd_env.o \
+ xray_re/xr_level_snd_static.o \
+ xray_re/xr_level_som.o \
+ xray_re/xr_level_spawn.o \
+ xray_re/xr_level_visuals.o \
+ xray_re/xr_level_wallmarks.o \
+ xray_re/xr_log.o \
+ xray_re/xr_lzhuf.o \
+ xray_re/xr_matrix.o \
+ xray_re/xr_mesh.o \
+ xray_re/xr_mesh_builder.o \
+ xray_re/xr_mesh_vbuf.o \
+ xray_re/xr_motion.o \
+ xray_re/xr_name_gen.o \
+ xray_re/xr_obj_motion.o \
+ xray_re/xr_object.o \
+ xray_re/xr_ogf.o \
+ xray_re/xr_ogf_v3.o \
+ xray_re/xr_ogf_v4.o \
+ xray_re/xr_packet.o \
+ xray_re/xr_quaternion.o \
+ xray_re/xr_reader.o \
+ xray_re/xr_reader_scrambler.o \
+ xray_re/xr_scene.o \
+ xray_re/xr_scene_ai_map.o \
+ xray_re/xr_scene_details.o \
+ xray_re/xr_scene_glows.o \
+ xray_re/xr_scene_groups.o \
+ xray_re/xr_scene_lights.o \
+ xray_re/xr_scene_objects.o \
+ xray_re/xr_scene_part.o \
+ xray_re/xr_scene_particles.o \
+ xray_re/xr_scene_portals.o \
+ xray_re/xr_scene_revision.o \
+ xray_re/xr_scene_sectors.o \
+ xray_re/xr_scene_shapes.o \
+ xray_re/xr_scene_sound_envs.o \
+ xray_re/xr_scene_sound_srcs.o \
+ xray_re/xr_scene_spawns.o \
+ xray_re/xr_scene_visuals.o \
+ xray_re/xr_scene_wallmarks.o \
+ xray_re/xr_scene_ways.o \
+ xray_re/xr_scrambler.o \
+ xray_re/xr_shaders_lib.o \
+ xray_re/xr_shaders_xrlc_lib.o \
+ xray_re/xr_skeleton.o \
+ xray_re/xr_skl_motion.o \
+ xray_re/xr_sound_thumbnail.o \
+ xray_re/xr_surface.o \
+ xray_re/xr_texture_thumbnail.o \
+ xray_re/xr_vector3.o \
+ xray_re/xr_writer.o
+
+converter_OBJS= utils/converter/batch_helper.o \
+ utils/converter/converter.o \
+ utils/converter/db_tools.o \
+ utils/converter/dds_tools.o \
+ utils/converter/dm_tools.o \
+ utils/converter/fancy_tools.o \
+ utils/converter/level_aux_mesh.o \
+ utils/converter/level_mesh.o \
+ utils/converter/level_mesh_commit.o \
+ utils/converter/level_mesh_ladders.o \
+ utils/converter/level_mesh_materials.o \
+ utils/converter/level_mesh_terrain.o \
+ utils/converter/level_tools.o \
+ utils/converter/level_tools_ai_map.o \
+ utils/converter/level_tools_debug_cform.o \
+ utils/converter/level_tools_details.o \
+ utils/converter/level_tools_glows.o \
+ utils/converter/level_tools_hom.o \
+ utils/converter/level_tools_lights.o \
+ utils/converter/level_tools_particles.o \
+ utils/converter/level_tools_portals.o \
+ utils/converter/level_tools_sectors.o \
+ utils/converter/level_tools_som.o \
+ utils/converter/level_tools_sound_envs.o \
+ utils/converter/level_tools_sound_srcs.o \
+ utils/converter/level_tools_spawns.o \
+ utils/converter/level_tools_visuals.o \
+ utils/converter/level_tools_wallmarks.o \
+ utils/converter/level_tools_ways.o \
+ utils/converter/object_tools.o \
+ utils/converter/ogf_tools.o \
+ utils/converter/ogg_tools.o \
+ utils/converter/opcode/Ice/IceAABB.o \
+ utils/converter/opcode/Ice/IceContainer.o \
+ utils/converter/opcode/Ice/IceHPoint.o \
+ utils/converter/opcode/Ice/IceMatrix4x4.o \
+ utils/converter/opcode/Ice/IcePoint.o \
+ utils/converter/opcode/Ice/IceRandom.o \
+ utils/converter/opcode/OPC_AABBTree.o \
+ utils/converter/opcode/OPC_BaseModel.o \
+ utils/converter/opcode/OPC_Collider.o \
+ utils/converter/opcode/OPC_MeshInterface.o \
+ utils/converter/opcode/OPC_Model.o \
+ utils/converter/opcode/OPC_OptimizedTree.o \
+ utils/converter/opcode/OPC_TreeBuilders.o \
+ utils/converter/opcode/OPC_TreeCollider.o \
+ utils/converter/xrdemo_tools.o
+
+.cpp.o:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<
+
+.cxx.o:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<
+
+all: converter
+
+converter: $(xray_re_OBJS) $(converter_OBJS)
+ $(CXX) $(LDFLAGS) -llzo2 -lnvcore -lnvimage -lnvtt -lvorbisfile -lz -o $@ $>
+
+.PHONY: all
diff --git a/games/xray_re-tools/files/patch-sources_3rd-party_nvtt_nvcore_Memory.h b/games/xray_re-tools/files/patch-sources_3rd-party_nvtt_nvcore_Memory.h
new file mode 100644
index 000000000000..b6b6833f06ad
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_3rd-party_nvtt_nvcore_Memory.h
@@ -0,0 +1,20 @@
+--- sources/3rd-party/nvtt/nvcore/Memory.h.orig 2018-09-02 12:42:44 UTC
++++ sources/3rd-party/nvtt/nvcore/Memory.h
+@@ -28,7 +28,7 @@ namespace nv
+
+ // Override new/delete
+
+-inline void * operator new (size_t size) throw()
++inline void * operator new (size_t size) _THROW_BAD_ALLOC
+ {
+ return nv::mem::malloc(size);
+ }
+@@ -38,7 +38,7 @@ inline void operator delete (void *p) throw()
+ nv::mem::free(p);
+ }
+
+-inline void * operator new [] (size_t size) throw()
++inline void * operator new [] (size_t size) _THROW_BAD_ALLOC
+ {
+ return nv::mem::malloc(size);
+ }
diff --git a/games/xray_re-tools/files/patch-sources_3rd-party_nvtt_nvcore_poshlib_posh.h b/games/xray_re-tools/files/patch-sources_3rd-party_nvtt_nvcore_poshlib_posh.h
new file mode 100644
index 000000000000..7448d82366c0
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_3rd-party_nvtt_nvcore_poshlib_posh.h
@@ -0,0 +1,14 @@
+--- sources/3rd-party/nvtt/nvcore/poshlib/posh.h.orig 2018-09-02 12:42:44 UTC
++++ sources/3rd-party/nvtt/nvcore/poshlib/posh.h
+@@ -293,6 +293,11 @@ Metrowerks:
+ # define POSH_OS_STRING "Linux"
+ #endif
+
++#if defined __FreeBSD__
++# define POSH_OS_LINUX 1
++# define POSH_OS_STRING "FreeBSD"
++#endif
++
+ #if defined __CYGWIN32__
+ # define POSH_OS_CYGWIN32 1
+ # define POSH_OS_STRING "Cygwin"
diff --git a/games/xray_re-tools/files/patch-sources_utils_converter_db__tools.cxx b/games/xray_re-tools/files/patch-sources_utils_converter_db__tools.cxx
new file mode 100644
index 000000000000..eecfd8e63402
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_utils_converter_db__tools.cxx
@@ -0,0 +1,63 @@
+--- sources/utils/converter/db_tools.cxx.orig 2018-09-02 12:42:44 UTC
++++ sources/utils/converter/db_tools.cxx
+@@ -1,6 +1,10 @@
+ #define NOMINMAX
+-#include <windows.h>
+ #include <cstring>
++#ifdef _WIN32
++#include <windows.h>
++#else
++#include <dirent.h>
++#endif
+ #include "db_tools.h"
+ #include "xr_scrambler.h"
+ #include "xr_lzhuf.h"
+@@ -10,7 +14,9 @@
+ #include "lzo/minilzo.h"
+ #include "crc32/crc32.h"
+
++#ifndef DB_DEBUG
+ #define DB_DEBUG 0
++#endif
+
+ using namespace xray_re;
+
+@@ -163,7 +169,7 @@ static bool write_file(xr_file_system& fs, const std::
+ lzo_uint size = size_real;
+ uint8_t* temp = new uint8_t[size];
+ if (lzo1x_decompress_safe(data, size_compressed, temp, &size, 0) != LZO_E_OK) {
+- delete temp;
++ delete[] temp;
+ return false;
+ }
+ data = temp;
+@@ -432,6 +438,7 @@ void db_packer::process_folder(const std::string& path
+ m_folders.push_back(path);
+ }
+ found:
++#ifdef _WIN32
+ WIN32_FIND_DATAA info;
+ HANDLE h = FindFirstFileA((m_root + path + '*').c_str(), &info);
+ if (h == INVALID_HANDLE_VALUE)
+@@ -446,6 +453,21 @@ found:
+ }
+ } while (FindNextFileA(h, &info));
+ FindClose(h);
++#else
++ DIR *dp;
++ struct dirent *de;
++ dp = opendir((m_root + path).c_str());
++ while ((de = readdir(dp)) != NULL) {
++ if (de->d_type == DT_DIR) {
++ if (strcmp(de->d_name, ".") != 0 &&
++ strcmp(de->d_name, "..") != 0)
++ process_folder((path + de->d_name) + '/');
++ } else {
++ process_file(path + de->d_name);
++ }
++ }
++ (void)closedir(dp);
++#endif
+ }
+
+ void db_packer::process_file(const std::string& path)
diff --git a/games/xray_re-tools/files/patch-sources_utils_converter_dds__tools.cxx b/games/xray_re-tools/files/patch-sources_utils_converter_dds__tools.cxx
new file mode 100644
index 000000000000..984dfe3a50ff
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_utils_converter_dds__tools.cxx
@@ -0,0 +1,42 @@
+--- sources/utils/converter/dds_tools.cxx.orig 2018-09-02 12:42:44 UTC
++++ sources/utils/converter/dds_tools.cxx
+@@ -1,5 +1,9 @@
+ #define NOMINMAX
++#ifdef _WIN32
+ #include <windows.h>
++#else
++#include <dirent.h>
++#endif
+ #include <cstring>
+ #include "dds_tools.h"
+ #include "xr_image.h"
+@@ -82,6 +86,7 @@ void dds_tools::process_file(const std::string& path)
+
+ void dds_tools::process_folder(const std::string& path)
+ {
++#ifdef _WIN32
+ WIN32_FIND_DATAA info;
+ HANDLE h = FindFirstFileA((m_textures + path + '*').c_str(), &info);
+ if (h == INVALID_HANDLE_VALUE)
+@@ -95,6 +100,21 @@ void dds_tools::process_folder(const std::string& path
+ }
+ } while (FindNextFileA(h, &info));
+ FindClose(h);
++#else
++ DIR *dp;
++ struct dirent *de;
++ dp = opendir((m_textures + path).c_str());
++ while ((de = readdir(dp)) != NULL) {
++ if (de->d_type == DT_DIR) {
++ if (strcmp(de->d_name, ".") != 0 &&
++ strcmp(de->d_name, "..") != 0)
++ process_folder((path + de->d_name) + '/');
++ } else {
++ process_file(path + de->d_name);
++ }
++ }
++ (void)closedir(dp);
++#endif
+ }
+
+ void dds_tools::process(const cl_parser& cl)
diff --git a/games/xray_re-tools/files/patch-sources_utils_converter_ogg__tools.cxx b/games/xray_re-tools/files/patch-sources_utils_converter_ogg__tools.cxx
new file mode 100644
index 000000000000..ab812fb13073
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_utils_converter_ogg__tools.cxx
@@ -0,0 +1,43 @@
+--- sources/utils/converter/ogg_tools.cxx.orig 2018-09-02 12:42:44 UTC
++++ sources/utils/converter/ogg_tools.cxx
+@@ -1,5 +1,10 @@
+ #define NOMINMAX
++#ifdef _WIN32
+ #include <windows.h>
++#else
++#include <dirent.h>
++#include <errno.h>
++#endif
+ #include "ogg_tools.h"
+ #include "xr_types.h"
+ #include "xr_file_system.h"
+@@ -277,6 +282,7 @@ void ogg_tools::process_file(const std::string& path)
+
+ void ogg_tools::process_folder(const std::string& path)
+ {
++#ifdef _WIN32
+ WIN32_FIND_DATAA info;
+ HANDLE h = FindFirstFileA((m_sounds + path + '*').c_str(), &info);
+ if (h == INVALID_HANDLE_VALUE)
+@@ -290,6 +296,21 @@ void ogg_tools::process_folder(const std::string& path
+ }
+ } while (FindNextFileA(h, &info));
+ FindClose(h);
++#else
++ DIR *dp;
++ struct dirent *de;
++ dp = opendir((m_sounds + path).c_str());
++ while ((de = readdir(dp)) != NULL) {
++ if (de->d_type == DT_DIR) {
++ if (strcmp(de->d_name, ".") != 0 &&
++ strcmp(de->d_name, "..") != 0)
++ process_folder((path + de->d_name) + '/');
++ } else {
++ process_file(path + de->d_name);
++ }
++ }
++ (void)closedir(dp);
++#endif
+ }
+
+ void ogg_tools::process(const cl_parser& cl)
diff --git a/games/xray_re-tools/files/patch-sources_utils_converter_opcode_Ice_IceTypes.h b/games/xray_re-tools/files/patch-sources_utils_converter_opcode_Ice_IceTypes.h
new file mode 100644
index 000000000000..365ea61800c6
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_utils_converter_opcode_Ice_IceTypes.h
@@ -0,0 +1,17 @@
+--- sources/utils/converter/opcode/Ice/IceTypes.h.orig 2018-09-02 12:42:44 UTC
++++ sources/utils/converter/opcode/Ice/IceTypes.h
+@@ -47,10 +47,10 @@
+ typedef unsigned char ubyte; //!< sizeof(ubyte) must be 1
+ typedef signed short sword; //!< sizeof(sword) must be 2
+ typedef unsigned short uword; //!< sizeof(uword) must be 2
+- typedef signed int sdword; //!< sizeof(sdword) must be 4
+- typedef unsigned int udword; //!< sizeof(udword) must be 4
+- typedef signed __int64 sqword; //!< sizeof(sqword) must be 8
+- typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8
++ typedef int32_t sdword; //!< sizeof(sdword) must be 4
++ typedef uint32_t udword; //!< sizeof(udword) must be 4
++ typedef int64_t sqword; //!< sizeof(sqword) must be 8
++ typedef uint64_t uqword; //!< sizeof(uqword) must be 8
+ typedef float float32; //!< sizeof(float32) must be 4
+ typedef double float64; //!< sizeof(float64) must be 4
+
diff --git a/games/xray_re-tools/files/patch-sources_utils_converter_opcode_Opcode.h b/games/xray_re-tools/files/patch-sources_utils_converter_opcode_Opcode.h
new file mode 100644
index 000000000000..93c4527de5b2
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_utils_converter_opcode_Opcode.h
@@ -0,0 +1,22 @@
+--- sources/utils/converter/opcode/Opcode.h.orig 2018-09-02 12:42:44 UTC
++++ sources/utils/converter/opcode/Opcode.h
+@@ -41,9 +41,17 @@
+ // Preprocessor
+ #ifndef ICE_NO_DLL
+ #ifdef OPCODE_EXPORTS
+- #define OPCODE_API __declspec(dllexport)
++ #ifdef __GNUC__
++ #define OPCODE_API __attribute__((visibility("default")))
++ #else
++ #define OPCODE_API __declspec(dllexport)
++ #endif
+ #else
+- #define OPCODE_API __declspec(dllimport)
++ #ifdef __GNUC__
++ #define OPCODE_API __attribute__((visibility("hidden")))
++ #else
++ #define OPCODE_API __declspec(dllimport)
++ #endif
+ #endif
+ #else
+ #define OPCODE_API
diff --git a/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system.cxx b/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system.cxx
new file mode 100644
index 000000000000..5f275adf9538
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system.cxx
@@ -0,0 +1,27 @@
+--- sources/xray_re/xr_file_system.cxx.orig 2018-09-02 12:42:44 UTC
++++ sources/xray_re/xr_file_system.cxx
+@@ -235,7 +235,7 @@ xr_reader* xr_file_system::r_open(const char* path, co
+ xr_writer* xr_file_system::w_open(const char* path, const char* name) const
+ {
+ const path_alias* pa = find_path_alias(path);
+- return pa ? w_open(pa->root + name) : false;
++ return pa ? w_open(pa->root + name) : 0x0;
+ }
+
+ bool xr_file_system::folder_exist(const char* path, const char* name) const
+@@ -256,6 +256,7 @@ uint32_t xr_file_system::file_age(const char* path, co
+ return pa ? file_age(pa->root + name) : 0;
+ }
+
++#if 0
+ bool xr_file_system::copy_file(const char* src_path, const char* src_name,
+ const char* tgt_path, const char* tgt_name) const
+ {
+@@ -269,6 +270,7 @@ bool xr_file_system::copy_file(const char* src_path, c
+ tgt_name = src_name;
+ return copy_file(src_pa->root + src_name, tgt_pa->root + tgt_name);
+ }
++#endif
+
+ bool xr_file_system::create_folder(const char* path, const char* name) const
+ {
diff --git a/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system__posix.cxx b/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system__posix.cxx
new file mode 100644
index 000000000000..96c8a0286a0a
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system__posix.cxx
@@ -0,0 +1,291 @@
+--- sources/xray_re/xr_file_system_posix.cxx.orig 2018-09-02 12:42:44 UTC
++++ sources/xray_re/xr_file_system_posix.cxx
+@@ -1,3 +1,288 @@
++#include <string>
++#include <cstdlib>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/uio.h>
++#include <sys/mman.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <string.h>
++#include <unistd.h>
+ #include "xr_file_system_posix.h"
++#include "xr_string_utils.h"
+
+ using namespace xray_re;
++
++static char *normalize_path(const char *path)
++{
++ char *temp = strdup(path);
++
++ for (int i = 0; temp[i]; i++) {
++ if (temp[i] == '\\')
++ temp[i] = '/';
++ }
++ return temp; // don't forget to free it!
++}
++
++bool xr_file_system::create_folder(const char* path) const
++{
++ char *temp = normalize_path(path);
++
++ if (read_only()) {
++ dbg("fs_ro: creating folder %s", temp);
++ return true;
++ }
++ bool done = mkdir(temp, 0777) == 0 || errno == EEXIST;
++ free(temp);
++ return done;
++}
++
++bool xr_file_system::create_path(const char* path) const
++{
++ char *temp = normalize_path(path);
++
++ if (read_only()) {
++ dbg("fs_ro: creating path %s", temp);
++ return true;
++ }
++
++ bool done = false;
++ for (char* p = temp; *p != 0; ++p) {
++ if (*p != '/')
++ continue;
++ *p = 0;
++ struct stat sb;
++ stat(temp, &sb);
++ if (stat(temp, &sb) == -1 && errno == ENOENT) {
++ if (mkdir(temp, 0777) == -1 && errno != EEXIST) {
++ goto out;
++ }
++ } else if ((sb.st_mode & S_IFDIR) == 0) {
++ goto out;
++ }
++ *p = '/';
++ }
++ done = mkdir(temp, 0777) == 0 || errno == EEXIST;
++out:
++ free(temp);
++ return done;
++}
++
++#define _MAX_FNAME 256
++#define _MAX_DIR _MAX_FNAME
++#define _MAX_EXT _MAX_FNAME
++
++void xr_file_system::split_path(const char* path, std::string* folder,
++ std::string* name, std::string* extension)
++{
++ char *_dir, *_name, *_ext;
++ char *temp = strdup(path);
++
++ // find last dot
++ char *last = strrchr(temp, '.');
++ if (last) {
++ _ext = last;
++ if (extension) {
++ extension->assign(_ext);
++ xr_strlwr(*extension);
++ }
++ *_ext = '\0';
++ }
++
++ // find last backslash or slash
++ last = strrchr(temp, '\\');
++ char *last2 = strrchr(temp, '/');
++ if (last2 > last)
++ last = last2;
++
++ if (last) {
++ _dir = temp;
++ *last++ = '\0';
++ _name = last;
++ } else {
++ _dir = "";
++ _name = temp;
++ }
++
++ if (folder) {
++ folder->assign(_dir);
++ xr_strlwr(*folder);
++ }
++ if (name) {
++ name->assign(_name);
++ xr_strlwr(*name);
++ }
++ free(temp);
++}
++
++bool xr_file_system::folder_exist(const char* path)
++{
++ char *temp = normalize_path(path);
++
++ struct stat sb;
++ bool ret = stat(temp, &sb) == -1 || (sb.st_mode & S_IFDIR) == 0;
++ free(temp);
++ return !ret;
++}
++
++bool xr_file_system::file_exist(const char* path)
++{
++ char *temp = normalize_path(path);
++
++ struct stat sb;
++ bool ret = stat(path, &sb) == -1 || (sb.st_mode & S_IFDIR) != 0;
++ free(temp);
++ return !ret;
++}
++
++size_t xr_file_system::file_length(const char* path)
++{
++ char *temp = normalize_path(path);
++
++ struct stat sb;
++ size_t len = (stat(path, &sb) == 0) ? sb.st_size : 0;
++ free(temp);
++ return len;
++}
++
++uint32_t xr_file_system::file_age(const char* path)
++{
++ char *temp = normalize_path(path);
++
++ struct stat st;
++ time_t age = (stat(path, &st) == 0) ? st.st_mtime : 0;
++ free(temp);
++ return uint32_t(age);
++}
++
++#if 0
++bool xr_file_system::copy_file(const char* src_path, const char* tgt_path) const
++{
++ if (read_only()) {
++ dbg("fs_ro: copying %s to %s", src_path, tgt_path);
++ return true;
++ }
++ return CopyFileA(src_path, tgt_path, FALSE) != FALSE;
++}
++#endif
++
++xr_reader* xr_file_system::r_open(const char* path) const
++{
++ char *temp = normalize_path(path);
++
++ struct stat sb;
++
++ if (stat(temp, &sb) == -1) {
++ free(temp);
++ return 0;
++ }
++ size_t len = sb.st_size;
++
++ int fd = open(temp, O_RDONLY);
++ if (fd == -1) {
++ free(temp);
++ return 0;
++ }
++
++ xr_reader* r = 0;
++
++ void *data;
++ if (len < getpagesize()) {
++ uint8_t *data = (uint8_t *)malloc(len);
++ if (data != NULL) {
++ if (read(fd, data, len) == len) {
++ r = new xr_temp_reader(data, len);
++ } else {
++ free(data);
++ }
++ }
++ close(fd);
++ free(temp);
++ return r;
++ }
++
++ data = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
++
++ if (data != MAP_FAILED) {
++ r = new xr_mmap_reader_posix(fd, data, len);
++ if (r) {
++ free(temp);
++ return r;
++ }
++ munmap(data, len);
++ }
++
++ close(fd);
++
++ return 0;
++}
++
++xr_writer* xr_file_system::w_open(const char* path, bool ignore_ro) const
++{
++ char *temp = normalize_path(path);
++
++ if (!ignore_ro && read_only()) {
++ dbg("fs_ro: writing %s", temp);
++ free(temp);
++ return new xr_fake_writer();
++ }
++
++ int fd = open(temp, O_WRONLY | O_CREAT, 0666);
++ if (fd == -1) {
++ if(errno == ENOENT) {
++ std::string folder;
++ split_path(temp, &folder);
++ if (!create_path(folder))
++ return 0;
++ return w_open(temp, ignore_ro);
++ }
++ else
++ return 0;
++ }
++ xr_writer* w = new xr_file_writer_posix(fd);
++ if (w == 0)
++ close(fd);
++ return w;
++}
++
++xr_mmap_reader_posix::xr_mmap_reader_posix(): m_fd(-1) {}
++
++xr_mmap_reader_posix::xr_mmap_reader_posix(int fd, const void* data, size_t size):
++ m_fd(fd)
++{
++ m_next = m_p = m_data = static_cast<const uint8_t*>(data);
++ m_end = m_data + size;
++}
++
++xr_mmap_reader_posix::~xr_mmap_reader_posix()
++{
++ assert(m_data != 0);
++ assert(m_fd != -1);
++ munmap(const_cast<uint8_t*>(m_data), m_end - m_data);
++ close(m_fd);
++}
++
++xr_file_writer_posix::xr_file_writer_posix(): m_fd(-1) {}
++
++xr_file_writer_posix::xr_file_writer_posix(int fd): m_fd(fd) {}
++
++xr_file_writer_posix::~xr_file_writer_posix()
++{
++ close(m_fd);
++}
++
++void xr_file_writer_posix::w_raw(const void* data, size_t size)
++{
++ xr_assert(write(m_fd, data, size) == size);
++}
++
++void xr_file_writer_posix::seek(size_t pos)
++{
++ off_t new_pos = lseek(m_fd, (off_t)pos, SEEK_SET);
++ xr_assert(pos == (size_t)new_pos);
++}
++
++size_t xr_file_writer_posix::tell()
++{
++ return lseek(m_fd, 0, SEEK_CUR);
++}
diff --git a/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system__posix.h b/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system__posix.h
new file mode 100644
index 000000000000..b7c22ddcb98a
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_xray__re_xr__file__system__posix.h
@@ -0,0 +1,32 @@
+--- sources/xray_re/xr_file_system_posix.h.orig 2018-09-02 12:42:44 UTC
++++ sources/xray_re/xr_file_system_posix.h
+@@ -8,6 +8,29 @@
+
+ namespace xray_re {
+
++class xr_mmap_reader_posix: public xr_reader {
++public:
++ xr_mmap_reader_posix();
++ xr_mmap_reader_posix(int fd, const void *data, size_t size);
++ virtual ~xr_mmap_reader_posix();
++
++private:
++ int m_fd;
++};
++
++class xr_file_writer_posix: public xr_writer {
++public:
++ xr_file_writer_posix();
++ xr_file_writer_posix(int fd);
++ virtual ~xr_file_writer_posix();
++ virtual void w_raw(const void* src, size_t src_size);
++ virtual void seek(size_t pos);
++ virtual size_t tell();
++
++private:
++ int m_fd;
++};
++
+ } // end of namespace xray_re
+
+ #endif
diff --git a/games/xray_re-tools/files/patch-sources_xray__re_xr__writer.cxx b/games/xray_re-tools/files/patch-sources_xray__re_xr__writer.cxx
new file mode 100644
index 000000000000..2e026d6c1695
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_xray__re_xr__writer.cxx
@@ -0,0 +1,11 @@
+--- sources/xray_re/xr_writer.cxx.orig 2018-09-02 12:42:44 UTC
++++ sources/xray_re/xr_writer.cxx
+@@ -176,7 +176,7 @@ void xr_ini_writer::open_section(std::string format, .
+ #if defined(_MSC_VER) && _MSC_VER >= 1400
+ int n = vsprintf_s(buf, sizeof(buf), format.c_str(), ap);
+ #else
+- int n = vsnprintf(buf, sizeof(buf), format, ap);
++ int n = vsnprintf(buf, sizeof(buf), format.c_str(), ap);
+ #endif
+ va_end(ap);
+ if (n == 0)
diff --git a/games/xray_re-tools/files/patch-sources_xray__re_xr__writer.h b/games/xray_re-tools/files/patch-sources_xray__re_xr__writer.h
new file mode 100644
index 000000000000..1fd78c9e0256
--- /dev/null
+++ b/games/xray_re-tools/files/patch-sources_xray__re_xr__writer.h
@@ -0,0 +1,14 @@
+--- sources/xray_re/xr_writer.h.orig 2018-09-02 12:42:44 UTC
++++ sources/xray_re/xr_writer.h
+@@ -268,9 +268,9 @@ template<typename T, typename F> inline void xr_ini_wr
+ template<typename T, typename F> inline void xr_ini_writer::w_ini_seq(const T& container, F write, const char* prefix)
+ {
+ char buf[1024];
++ typename T::const_iterator it = container.begin(), end = container.end();
+
+- for (uint32_t id = 0, typename T::const_iterator it = container.begin(),
+- end = container.end(); it != end; ++it, ++id) {
++ for (uint32_t id = 0; it != end; ++it, ++id) {
+ #if defined(_MSC_VER) && _MSC_VER >= 1400
+ int n = sprintf_s(buf, sizeof(buf), "%s_%04d", prefix, id);
+ #else
diff --git a/games/xray_re-tools/pkg-descr b/games/xray_re-tools/pkg-descr
new file mode 100644
index 000000000000..617829235125
--- /dev/null
+++ b/games/xray_re-tools/pkg-descr
@@ -0,0 +1,11 @@
+Portable (POSIX) subset of the X-Ray unofficial toolset used for modding the
+S.T.A.L.K.E.R. game series by GSC Game World. Currently includes standalone
+converter utility which is useful for casual gamers to unpack game resources.
+
+Usage examples, first for Russian release version of Shadow of Chernobyl and
+second for Clear Sky and Call of Pripyat:
+
+ $ xr_converter -unpack /path/to/gamedata.db0 -2947ru -dir ./put_it_here
+ $ xr_converter -unpack /path/to/resources.db0 -xdb -dir ./put_it_here
+
+WWW: https://github.com/abramcumner/xray_re-tools