diff --git a/regamedll/CMakeLists.txt b/regamedll/CMakeLists.txt
index bc0a990e..c1a13f9b 100644
--- a/regamedll/CMakeLists.txt
+++ b/regamedll/CMakeLists.txt
@@ -20,20 +20,47 @@
cmake_minimum_required(VERSION 3.1)
project(regamedll CXX)
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
option(DEBUG "Build with debug information." OFF)
option(USE_STATIC_LIBSTDC "Enables static linking libstdc++." OFF)
option(USE_LEGACY_LIBC "Enables linking against legacy libc (<= 2.15) for compat with older distros (Debian 8/Ubuntu 16.04/Centos 7)." OFF)
+option(XASH_COMPAT "Enable Xash3D FWGS compatiblity (support for it's 64-bit ABI support and crossplatform library suffix)")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Avoid -rdynamic -fPIC options
-set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "")
-set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+if (NOT XASH_COMPAT)
+ set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "")
+ set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+endif()
-set(COMPILE_FLAGS "-m32 -U_FORTIFY_SOURCE")
-set(LINK_FLAGS "-m32 -s")
-set(LINK_LIBS dl aelf32)
+set(COMPILE_FLAGS "-U_FORTIFY_SOURCE")
+set(LINK_LIBS dl)
+
+# do not strip debuginfo during link
+if (NOT DEBUG)
+ set(LINK_FLAGS "-s")
+endif()
+
+# add -m32 flag only on 64-bit systems, if building for 64-bit wasn't enabled with XASH_COMPAT
+if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+ if (XASH_COMPAT)
+ set(COMPILE_FLAGS "${COMPILE_FLAGS} -DXASH_64BIT")
+ else()
+ set(COMPILE_FLAGS "${COMPILE_FLAGS} -m32")
+ set(LINK_FLAGS "${LINK_FLAGS} -m32")
+ list(APPEND LINK_LIBS aelf32)
+ set(CMAKE_SIZEOF_VOID_P 4)
+ endif()
+endif()
+
+if(XASH_COMPAT)
+ # Xash3D FWGS Library Naming Scheme compliance
+ # see documentation: https://github.com/FWGS/xash3d-fwgs/blob/master/Documentation/extensions/library-naming.md
+ include(LibraryNaming)
+endif()
set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wall -fno-exceptions -fno-builtin -Wno-unknown-pragmas")
@@ -47,7 +74,7 @@ else()
endif()
# Check Intel C++ compiler
-if ("$ENV{CXX}" MATCHES "icpc")
+if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
#
# -fp-model=precise
# ICC uses -fp-model fast=1 by default for more aggressive optimizations on floating-point calculations
@@ -75,11 +102,15 @@ if ("$ENV{CXX}" MATCHES "icpc")
set(COMPILE_FLAGS "${COMPILE_FLAGS} -ipo")
set(LINK_FLAGS "${LINK_FLAGS} -ipo")
endif()
-else()
- # Produce code optimized for the most common IA32/AMD64/EM64T processors.
- # As new processors are deployed in the marketplace, the behavior of this option will change.
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ if (NOT XASH_COMPAT OR XASH_AMD64 OR XASH_X86)
+ # Produce code optimized for the most common IA32/AMD64/EM64T processors.
+ # As new processors are deployed in the marketplace, the behavior of this option will change.
+ set(COMPILE_FLAGS "${COMPILE_FLAGS} \
+ -mtune=generic -msse3")
+ endif()
+
set(COMPILE_FLAGS "${COMPILE_FLAGS} \
- -mtune=generic -msse3\
-fpermissive -fno-sized-deallocation\
-Wno-delete-non-virtual-dtor -Wno-invalid-offsetof\
-Wno-unused-variable -Wno-unused-value -Wno-unused-result -Wno-unused-function\
@@ -87,7 +118,7 @@ else()
-Wno-sign-compare -Wno-format -Wno-ignored-attributes -Wno-strict-aliasing")
# Check Clang compiler
- if ("$ENV{CXX}" MATCHES "clang")
+ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(COMPILE_FLAGS "${COMPILE_FLAGS} \
-Wno-unused-local-typedef\
-Wno-unused-private-field\
@@ -102,16 +133,11 @@ else()
# GCC >= 8.3
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
- set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-stringop-truncation -Wno-format-truncation -Wno-class-memaccess")
+ set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-stringop-truncation -Wno-format-truncation -Wno-class-memaccess -fcf-protection=none")
endif()
endif()
endif()
-# GCC >= 8.3
-if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
- set(COMPILE_FLAGS "${COMPILE_FLAGS} -fcf-protection=none")
-endif()
-
if (NOT DEBUG)
set(LINK_FLAGS "${LINK_FLAGS} \
-Wl,-gc-sections -Wl,--version-script=\"${PROJECT_SOURCE_DIR}/../version_script.lds\"")
@@ -378,14 +404,36 @@ if (USE_STATIC_LIBSTDC)
set(LINK_FLAGS "${LINK_FLAGS} -static-libgcc -static-libstdc++")
endif()
-set(LINK_FLAGS "${LINK_FLAGS} \
- -Wl,-rpath,'$ORIGIN/.' \
- -L${PROJECT_SOURCE_DIR}/lib/linux32")
+set(LINK_FLAGS "${LINK_FLAGS} -Wl,-rpath,'$ORIGIN/.'")
+
+if (CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set(LINK_FLAGS "${LINK_FLAGS} -L${PROJECT_SOURCE_DIR}/lib/linux32")
+endif()
set_target_properties(regamedll PROPERTIES
- OUTPUT_NAME cs
- PREFIX ""
COMPILE_FLAGS ${COMPILE_FLAGS}
LINK_FLAGS ${LINK_FLAGS}
- POSITION_INDEPENDENT_CODE OFF
)
+
+if (XASH_COMPAT)
+ if (CMAKE_SYSTEM_NAME STREQUAL "Android")
+ set_target_properties(regamedll PROPERTIES
+ OUTPUT_NAME server)
+ else()
+ set_target_properties(regamedll PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME cs${POSTFIX})
+ endif()
+else()
+ set_target_properties(regamedll PROPERTIES
+ OUTPUT_NAME cs
+ PREFIX ""
+ POSITION_INDEPENDENT_CODE OFF)
+endif()
+
+install(TARGETS regamedll
+ RUNTIME DESTINATION "cstrike/dlls/"
+ LIBRARY DESTINATION "cstrike/dlls/"
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE)
diff --git a/regamedll/cmake/LibraryNaming.cmake b/regamedll/cmake/LibraryNaming.cmake
new file mode 100644
index 00000000..a20529ae
--- /dev/null
+++ b/regamedll/cmake/LibraryNaming.cmake
@@ -0,0 +1,198 @@
+include(CheckSymbolExists)
+
+macro(check_build_target symbol)
+ check_symbol_exists(${symbol} "build.h" ${symbol})
+endmacro()
+
+macro(check_group_build_target symbol group)
+ if(NOT ${group})
+ check_build_target(${symbol})
+ if(${symbol})
+ set(${group} TRUE)
+ endif()
+ else()
+ set(${symbol} FALSE)
+ endif()
+endmacro()
+
+# So there is a problem:
+# 1. Number of these symbols only grows, as we support more and more ports
+# 2. CMake was written by morons and can't check these symbols in parallel
+# 3. MSVC is very slow at everything (startup, parsing, generating error)
+
+# Solution: group these symbols and set variable if one of them was found
+# this way we can reorder to reorder them by most common configurations
+# but we can't generate this list anymore! ... OR IS IT ???
+
+# Well, after reordering positions in engine's buildenums.h, we can partially autogenerate this list!
+# echo "check_build_target(XASH_64BIT)"
+# grep "#define PLATFORM" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 " XASH_PLATFORM)" }'
+# grep "#define ARCHITECTURE" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 " XASH_ARCHITECTURE)"
+# grep "#define ENDIAN" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 "_ENDIAN XASH_ENDIANNESS)"}'
+# echo "if(XASH_ARM)"
+# grep '^#undef XASH' build.h | grep "XASH_ARM[v_]" | awk '{ print "check_build_target(" $2 ")"}'
+# echo "endif()"
+# echo "if(XASH_RISCV)"
+# grep '^#undef XASH' build.h | grep "XASH_RISCV_" | awk '{ print "check_build_target(" $2 ")"}'
+# echo "endif()"
+
+# NOTE: Android must have priority over Linux to work correctly!
+
+set(CMAKE_REQUIRED_INCLUDES "${PROJECT_SOURCE_DIR}/public/")
+check_build_target(XASH_64BIT)
+check_group_build_target(XASH_WIN32 XASH_PLATFORM)
+check_group_build_target(XASH_ANDROID XASH_PLATFORM)
+check_group_build_target(XASH_LINUX XASH_PLATFORM)
+check_group_build_target(XASH_FREEBSD XASH_PLATFORM)
+check_group_build_target(XASH_APPLE XASH_PLATFORM)
+check_group_build_target(XASH_NETBSD XASH_PLATFORM)
+check_group_build_target(XASH_OPENBSD XASH_PLATFORM)
+check_group_build_target(XASH_EMSCRIPTEN XASH_PLATFORM)
+check_group_build_target(XASH_DOS4GW XASH_PLATFORM)
+check_group_build_target(XASH_HAIKU XASH_PLATFORM)
+check_group_build_target(XASH_SERENITY XASH_PLATFORM)
+check_group_build_target(XASH_IRIX XASH_PLATFORM)
+check_group_build_target(XASH_NSWITCH XASH_PLATFORM)
+check_group_build_target(XASH_PSVITA XASH_PLATFORM)
+check_group_build_target(XASH_WASI XASH_PLATFORM)
+check_group_build_target(XASH_SUNOS XASH_PLATFORM)
+check_group_build_target(XASH_X86 XASH_ARCHITECTURE)
+check_group_build_target(XASH_AMD64 XASH_ARCHITECTURE)
+check_group_build_target(XASH_ARM XASH_ARCHITECTURE)
+check_group_build_target(XASH_MIPS XASH_ARCHITECTURE)
+check_group_build_target(XASH_PPC XASH_ARCHITECTURE)
+check_group_build_target(XASH_JS XASH_ARCHITECTURE)
+check_group_build_target(XASH_E2K XASH_ARCHITECTURE)
+check_group_build_target(XASH_RISCV XASH_ARCHITECTURE)
+check_group_build_target(XASH_LITTLE_ENDIAN XASH_ENDIANNESS)
+check_group_build_target(XASH_BIG_ENDIAN XASH_ENDIANNESS)
+if(XASH_ARM)
+check_build_target(XASH_ARM_HARDFP)
+check_build_target(XASH_ARM_SOFTFP)
+check_build_target(XASH_ARMv4)
+check_build_target(XASH_ARMv5)
+check_build_target(XASH_ARMv6)
+check_build_target(XASH_ARMv7)
+check_build_target(XASH_ARMv8)
+endif()
+if(XASH_RISCV)
+check_build_target(XASH_RISCV_DOUBLEFP)
+check_build_target(XASH_RISCV_SINGLEFP)
+check_build_target(XASH_RISCV_SOFTFP)
+endif()
+unset(CMAKE_REQUIRED_INCLUDES)
+
+# engine/common/build.c
+if(XASH_ANDROID)
+ set(BUILDOS "android")
+elseif(XASH_WIN32 OR XASH_LINUX OR XASH_APPLE)
+ set(BUILDOS "") # no prefix for default OS
+elseif(XASH_FREEBSD)
+ set(BUILDOS "freebsd")
+elseif(XASH_NETBSD)
+ set(BUILDOS "netbsd")
+elseif(XASH_OPENBSD)
+ set(BUILDOS "openbsd")
+elseif(XASH_EMSCRIPTEN)
+ set(BUILDOS "emscripten")
+elseif(XASH_DOS4GW)
+ set(BUILDOS "DOS4GW")
+elseif(XASH_HAIKU)
+ set(BUILDOS "haiku")
+elseif(XASH_SERENITY)
+ set(BUILDOS "serenityos")
+elseif(XASH_NSWITCH)
+ set(BUILDOS "nswitch")
+elseif(XASH_PSVITA)
+ set(BUILDOS "psvita")
+elseif(XASH_IRIX)
+ set(BUILDOS "irix")
+elseif(XASH_WASI)
+ set(BUILDOS "wasi")
+elseif(XASH_SUNOS)
+ set(BUILDOS "sunos")
+else()
+ message(SEND_ERROR "Place your operating system name here! If this is a mistake, try to fix conditions above and report a bug")
+endif()
+
+if(XASH_AMD64)
+ set(BUILDARCH "amd64")
+elseif(XASH_X86)
+ if(XASH_WIN32 OR XASH_LINUX OR XASH_APPLE)
+ set(BUILDARCH "") # no prefix for default OS
+ else()
+ set(BUILDARCH "i386")
+ endif()
+elseif(XASH_ARM AND XASH_64BIT)
+ set(BUILDARCH "arm64")
+elseif(XASH_ARM)
+ set(BUILDARCH "armv")
+ if(XASH_ARMv8)
+ set(BUILDARCH "${BUILDARCH}8_32")
+ elseif(XASH_ARMv7)
+ set(BUILDARCH "${BUILDARCH}7")
+ elseif(XASH_ARMv6)
+ set(BUILDARCH "${BUILDARCH}6")
+ elseif(XASH_ARMv5)
+ set(BUILDARCH "${BUILDARCH}5")
+ elseif(XASH_ARMv4)
+ set(BUILDARCH "${BUILDARCH}4")
+ else()
+ message(SEND_ERROR "Unknown ARM")
+ endif()
+
+ if(XASH_ARM_HARDFP)
+ set(BUILDARCH "${BUILDARCH}hf")
+ else()
+ set(BUILDARCH "${BUILDARCH}l")
+ endif()
+elseif(XASH_MIPS)
+ set(BUILDARCH "mips")
+ if(XASH_64BIT)
+ set(BUILDARCH "${BUILDARCH}64")
+ endif()
+
+ if(XASH_LITTLE_ENDIAN)
+ set(BUILDARCH "${BUILDARCH}el")
+ endif()
+elseif(XASH_RISCV)
+ set(BUILDARCH "riscv")
+ if(XASH_64BIT)
+ set(BUILDARCH "${BUILDARCH}64")
+ else()
+ set(BUILDARCH "${BUILDARCH}32")
+ endif()
+
+ if(XASH_RISCV_DOUBLEFP)
+ set(BUILDARCH "${BUILDARCH}d")
+ elseif(XASH_RISCV_SINGLEFP)
+ set(BUILDARCH "${BUILDARCH}f")
+ endif()
+elseif(XASH_JS)
+ set(BUILDARCH "javascript")
+elseif(XASH_E2K)
+ set(BUILDARCH "e2k")
+elseif(XASH_PPC)
+ set(BUILDARCH "ppc")
+ if(XASH_64BIT)
+ set(BUILDARCH "${BUILDARCH}64")
+ endif()
+
+ if(XASH_LITTLE_ENDIAN)
+ set(BUILDARCH "${BUILDARCH}el")
+ endif()
+else()
+ message(SEND_ERROR "Place your architecture name here! If this is a mistake, try to fix conditions above and report a bug")
+endif()
+
+if(BUILDOS STREQUAL "android")
+ set(POSTFIX "") # force disable for Android, as Android ports aren't distributed in normal way and doesn't follow library naming
+elseif(BUILDOS AND BUILDARCH)
+ set(POSTFIX "_${BUILDOS}_${BUILDARCH}")
+elseif(BUILDARCH)
+ set(POSTFIX "_${BUILDARCH}")
+else()
+ set(POSTFIX "")
+endif()
+
+message(STATUS "Library postfix: " ${POSTFIX})
diff --git a/regamedll/dlls/qstring.h b/regamedll/dlls/qstring.h
index 0b158292..1f5d679d 100644
--- a/regamedll/dlls/qstring.h
+++ b/regamedll/dlls/qstring.h
@@ -30,16 +30,18 @@
#define QSTRING_DEFINE
-constexpr unsigned int iStringNull = {0};
-
// Quake string (helper class)
class QString final
{
public:
+#if XASH_64BIT
+ using qstring_t = int;
+#else
using qstring_t = unsigned int;
+#endif
- QString(): m_string(iStringNull) {};
- QString(qstring_t string): m_string(string) {};
+ QString();
+ QString(qstring_t string);
bool IsNull() const;
bool IsNullOrEmpty() const;
@@ -52,13 +54,15 @@ public:
bool operator==(const char *pszString) const;
operator const char *() const;
- operator unsigned int() const;
+ operator qstring_t() const;
const char *str() const;
private:
qstring_t m_string;
};
+constexpr QString::qstring_t iStringNull = {0};
+
#ifdef USE_QSTRING
#define string_t QString
#endif
@@ -70,10 +74,25 @@ private:
extern globalvars_t *gpGlobals;
-#define STRING(offset) ((const char *)(gpGlobals->pStringBase + (unsigned int)(offset)))
-#define MAKE_STRING(str) ((unsigned int)(str) - (unsigned int)(STRING(0)))
+#define STRING(offset) ((const char *)(gpGlobals->pStringBase + (QString::qstring_t)(offset)))
+#if XASH_64BIT
+// Xash3D FWGS in 64-bit mode has internal string pool which allows mods to continue use 32-bit string_t
+inline int MAKE_STRING(const char *str)
+{
+ ptrdiff_t diff = str - STRING(0);
+ if (diff >= INT_MIN && diff <= INT_MAX)
+ return (int)diff;
+
+ return ALLOC_STRING(str);
+}
+#else
+#define MAKE_STRING(str) ((QString::qstring_t)(str) - (QString::qstring_t)(STRING(0)))
+#endif
// Inlines
+inline QString::QString(): m_string(iStringNull) {}
+inline QString::QString(qstring_t string): m_string(string) {}
+
inline bool QString::IsNull() const
{
return m_string == iStringNull;
@@ -115,7 +134,7 @@ inline QString::operator const char *() const
return str();
}
-inline QString::operator unsigned int() const
+inline QString::operator qstring_t() const
{
return m_string;
}
diff --git a/regamedll/public/build.h b/regamedll/public/build.h
new file mode 100644
index 00000000..24fd9d5b
--- /dev/null
+++ b/regamedll/public/build.h
@@ -0,0 +1,269 @@
+/*
+build.h - compile-time build information
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to
+*/
+#pragma once
+#ifndef BUILD_H
+#define BUILD_H
+
+/*
+All XASH_* macros set by this header are guaranteed to have positive value
+otherwise not defined.
+
+Every macro is intended to be the unified interface for buildsystems that lack
+platform & CPU detection, and a neat quick way for checks in platform code
+For Q_build* macros, refer to buildenums.h
+
+Any new define must be undefined at first
+You can generate #undef list below with this oneliner:
+ $ sed 's/\t//g' build.h | grep '^#define XASH' | awk '{ print $2 }' | \
+ sort | uniq | awk '{ print "#undef " $1 }'
+
+Then you can use another oneliner to query all variables:
+ $ grep '^#undef XASH' build.h | awk '{ print $2 }'
+*/
+
+#undef XASH_64BIT
+#undef XASH_AMD64
+#undef XASH_ANDROID
+#undef XASH_APPLE
+#undef XASH_ARM
+#undef XASH_ARM_HARDFP
+#undef XASH_ARM_SOFTFP
+#undef XASH_ARMv4
+#undef XASH_ARMv5
+#undef XASH_ARMv6
+#undef XASH_ARMv7
+#undef XASH_ARMv8
+#undef XASH_BIG_ENDIAN
+#undef XASH_DOS4GW
+#undef XASH_E2K
+#undef XASH_EMSCRIPTEN
+#undef XASH_FREEBSD
+#undef XASH_HAIKU
+#undef XASH_IOS
+#undef XASH_IRIX
+#undef XASH_JS
+#undef XASH_LINUX
+#undef XASH_LITTLE_ENDIAN
+#undef XASH_MIPS
+#undef XASH_MOBILE_PLATFORM
+#undef XASH_NETBSD
+#undef XASH_OPENBSD
+#undef XASH_POSIX
+#undef XASH_PPC
+#undef XASH_RISCV
+#undef XASH_RISCV_DOUBLEFP
+#undef XASH_RISCV_SINGLEFP
+#undef XASH_RISCV_SOFTFP
+#undef XASH_SERENITY
+#undef XASH_SUNOS
+#undef XASH_WIN32
+#undef XASH_X86
+#undef XASH_NSWITCH
+#undef XASH_PSVITA
+#undef XASH_WASI
+#undef XASH_WASM
+
+//================================================================
+//
+// PLATFORM DETECTION CODE
+//
+//================================================================
+#if defined _WIN32
+ #define XASH_WIN32 1
+#elif defined __EMSCRIPTEN__
+ #define XASH_EMSCRIPTEN 1
+#elif defined __WATCOMC__ && defined __DOS__
+ #define XASH_DOS4GW 1
+#else // POSIX compatible
+ #define XASH_POSIX 1
+ #if defined __linux__
+ #if defined __ANDROID__
+ #define XASH_ANDROID 1
+ #endif
+ #define XASH_LINUX 1
+ #elif defined __FreeBSD__
+ #define XASH_FREEBSD 1
+ #elif defined __NetBSD__
+ #define XASH_NETBSD 1
+ #elif defined __OpenBSD__
+ #define XASH_OPENBSD 1
+ #elif defined __HAIKU__
+ #define XASH_HAIKU 1
+ #elif defined __serenity__
+ #define XASH_SERENITY 1
+ #elif defined __sgi
+ #define XASH_IRIX 1
+ #elif defined __APPLE__
+ #include
+ #define XASH_APPLE 1
+ #if TARGET_OS_IOS
+ #define XASH_IOS 1
+ #endif // TARGET_OS_IOS
+ #elif defined __SWITCH__
+ #define XASH_NSWITCH 1
+ #elif defined __vita__
+ #define XASH_PSVITA 1
+ #elif defined __wasi__
+ #define XASH_WASI 1
+ #elif defined __sun__
+ #define XASH_SUNOS 1
+ #else
+ #error
+ #endif
+#endif
+
+// XASH_SAILFISH is special: SailfishOS by itself is a normal GNU/Linux platform
+// It doesn't make sense to split it to separate platform
+// but we still need XASH_MOBILE_PLATFORM for the engine.
+// So this macro is defined entirely in build-system: see main wscript
+// HLSDK/PrimeXT/other SDKs users note: you may ignore this macro
+#if XASH_ANDROID || XASH_IOS || XASH_NSWITCH || XASH_PSVITA || XASH_SAILFISH
+ #define XASH_MOBILE_PLATFORM 1
+#endif
+
+//================================================================
+//
+// ENDIANNESS DEFINES
+//
+//================================================================
+
+#if !defined XASH_ENDIANNESS
+ #if defined XASH_WIN32 || __LITTLE_ENDIAN__
+ //!!! Probably all WinNT installations runs in little endian
+ #define XASH_LITTLE_ENDIAN 1
+ #elif __BIG_ENDIAN__
+ #define XASH_BIG_ENDIAN 1
+ #elif defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__ && defined __ORDER_LITTLE_ENDIAN__ // some compilers define this
+ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ #define XASH_BIG_ENDIAN 1
+ #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ #define XASH_LITTLE_ENDIAN 1
+ #endif
+ #else
+ #include
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ #define XASH_BIG_ENDIAN 1
+ #elif __BYTE_ORDER == __LITTLE_ENDIAN
+ #define XASH_LITTLE_ENDIAN 1
+ #endif
+ #endif // !XASH_WIN32
+#endif
+
+//================================================================
+//
+// CPU ARCHITECTURE DEFINES
+//
+//================================================================
+#if defined __x86_64__ || defined _M_X64
+ #define XASH_64BIT 1
+ #define XASH_AMD64 1
+#elif defined __i386__ || defined _X86_ || defined _M_IX86
+ #define XASH_X86 1
+#elif defined __aarch64__ || defined _M_ARM64
+ #define XASH_64BIT 1
+ #define XASH_ARM 8
+#elif defined __mips__
+ #define XASH_MIPS 1
+#elif defined __EMSCRIPTEN__
+ #define XASH_JS 1
+#elif defined __e2k__
+ #define XASH_64BIT 1
+ #define XASH_E2K 1
+#elif defined __PPC__ || defined __powerpc__
+ #define XASH_PPC 1
+ #if defined __PPC64__ || defined __powerpc64__
+ #define XASH_64BIT 1
+ #endif
+#elif defined _M_ARM // msvc
+ #define XASH_ARM 7
+ #define XASH_ARM_HARDFP 1
+#elif defined __arm__
+ #if __ARM_ARCH == 8 || __ARM_ARCH_8__
+ #define XASH_ARM 8
+ #elif __ARM_ARCH == 7 || __ARM_ARCH_7__
+ #define XASH_ARM 7
+ #elif __ARM_ARCH == 6 || __ARM_ARCH_6__ || __ARM_ARCH_6J__
+ #define XASH_ARM 6
+ #elif __ARM_ARCH == 5 || __ARM_ARCH_5__
+ #define XASH_ARM 5
+ #elif __ARM_ARCH == 4 || __ARM_ARCH_4__
+ #define XASH_ARM 4
+ #else
+ #error "Unknown ARM"
+ #endif
+
+ #if defined __SOFTFP__ || __ARM_PCS_VFP == 0
+ #define XASH_ARM_SOFTFP 1
+ #else // __SOFTFP__
+ #define XASH_ARM_HARDFP 1
+ #endif // __SOFTFP__
+#elif defined __riscv
+ #define XASH_RISCV 1
+
+ #if __riscv_xlen == 64
+ #define XASH_64BIT 1
+ #elif __riscv_xlen != 32
+ #error "Unknown RISC-V ABI"
+ #endif
+
+ #if defined __riscv_float_abi_soft
+ #define XASH_RISCV_SOFTFP 1
+ #elif defined __riscv_float_abi_single
+ #define XASH_RISCV_SINGLEFP 1
+ #elif defined __riscv_float_abi_double
+ #define XASH_RISCV_DOUBLEFP 1
+ #else
+ #error "Unknown RISC-V float ABI"
+ #endif
+#elif defined __wasm__
+ #if defined __wasm64__
+ #define XASH_64BIT 1
+ #endif
+ #define XASH_WASM 1
+#else
+ #error "Place your architecture name here! If this is a mistake, try to fix conditions above and report a bug"
+#endif
+
+#if !XASH_64BIT && ( defined( __LP64__ ) || defined( _LP64 ))
+#define XASH_64BIT 1
+#endif
+
+#if XASH_ARM == 8
+ #define XASH_ARMv8 1
+#elif XASH_ARM == 7
+ #define XASH_ARMv7 1
+#elif XASH_ARM == 6
+ #define XASH_ARMv6 1
+#elif XASH_ARM == 5
+ #define XASH_ARMv5 1
+#elif XASH_ARM == 4
+ #define XASH_ARMv4 1
+#endif
+
+#endif // BUILD_H