code:
// Compatibility declarations for things which might not be present in
// certain build environments. It also levels the playing field caused
// by different platforms.

#ifndef compat_h_
#define compat_h_

#pragma once

#ifdef _WIN32
# include "windows_inc.h"
#endif

////////// Compiler detection //////////

#ifdef __GNUC__
# define EDUKE32_GCC_PREREQ(major, minor) (major < __GNUC__ || (major == __GNUC__ && minor <= __GNUC_MINOR__))
#else
# define EDUKE32_GCC_PREREQ(major, minor) 0
#endif

#ifdef __clang__
# define EDUKE32_CLANG_PREREQ(major, minor) (major < __clang_major__ || (major == __clang_major__ && minor <= __clang_minor__))
#else
# define EDUKE32_CLANG_PREREQ(major, minor) 0
#endif
#ifndef __has_builtin
# define __has_builtin(x) 0  // Compatibility with non-clang compilers.
#endif
#ifndef __has_feature
# define __has_feature(x) 0  // Compatibility with non-clang compilers.
#endif
#ifndef __has_extension
# define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
#endif
#ifndef __has_cpp_attribute
# define __has_cpp_attribute(x) 0
#endif

#ifdef _MSC_VER
# define EDUKE32_MSVC_PREREQ(major) ((major) <= (_MSC_VER))
# ifdef __cplusplus
#  define EDUKE32_MSVC_CXX_PREREQ(major) ((major) <= (_MSC_VER))
# else
#  define EDUKE32_MSVC_CXX_PREREQ(major) 0
# endif
#else
# define EDUKE32_MSVC_PREREQ(major) 0
# define EDUKE32_MSVC_CXX_PREREQ(major) 0
#endif

////////// Language detection //////////

#if defined __STDC__
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
#  define CSTD 2011
# elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#  define CSTD 1999
# elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199409L
#  define CSTD 1994
# else
#  define CSTD 1989
# endif
#else
# define CSTD 0
#endif

#if defined __cplusplus && __cplusplus >= 202002L
# define CXXSTD 2020
#elif defined __cplusplus && __cplusplus >= 201703L
# define CXXSTD 2017
#elif defined __cplusplus && __cplusplus >= 201402L
# define CXXSTD 2014
#elif defined __cplusplus && __cplusplus >= 201103L
# define CXXSTD 2011
#elif defined __cplusplus && __cplusplus >= 199711L
# define CXXSTD 1998
#else
# define CXXSTD 0
#endif

////////// Language and compiler feature polyfills //////////

#ifdef __cplusplus
# define EXTERNC extern "C"
#else
# define EXTERNC
#endif

#ifndef UNREFERENCED_PARAMETER
# define UNREFERENCED_PARAMETER(x) (x) = (x)
#endif

#ifndef UNREFERENCED_CONST_PARAMETER
# ifdef _MSC_VER
#  define UNREFERENCED_CONST_PARAMETER(x) ((void)(x))
# else
#  define UNREFERENCED_CONST_PARAMETER(x)
# endif
#endif

#ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
# define PRINTF_FORMAT(stringindex, firstargindex) __attribute__((format (printf, stringindex, firstargindex)))
#else
# define UNUSED(x) x
# define PRINTF_FORMAT(stringindex, firstargindex)
#endif

#if defined __GNUC__ || defined __clang__
# define ATTRIBUTE(attrlist) __attribute__(attrlist)
#else
# define ATTRIBUTE(attrlist)
#endif

#if !defined __clang__ && !defined USING_LTO
# define ATTRIBUTE_OPTIMIZE(str) ATTRIBUTE((optimize(str)))
#else
# define ATTRIBUTE_OPTIMIZE(str)
#endif

#if EDUKE32_GCC_PREREQ(4,0)
# define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
# define WARN_UNUSED_RESULT
#endif

#if defined _MSC_VER && _MSC_VER < 1800
# define inline __inline
#endif

#ifndef MAY_ALIAS
# ifdef _MSC_VER
#  define MAY_ALIAS
# else
#  define MAY_ALIAS __attribute__((may_alias))
# endif
#endif

#ifndef FORCE_INLINE
# ifdef _MSC_VER
#  define FORCE_INLINE __forceinline
# else
#  ifdef __GNUC__
#    define FORCE_INLINE inline __attribute__((always_inline))
#  else
#    define FORCE_INLINE inline
#  endif
# endif
#endif

#ifndef _MSC_VER
#  ifndef __fastcall
#    if defined(__GNUC__) && defined(__i386__)
#      define __fastcall __attribute__((fastcall))
#    else
#      define __fastcall
#    endif
#  endif
#endif

#ifndef DISABLE_INLINING
# define EXTERN_INLINE static inline
# define EXTERN_INLINE_HEADER static inline
#else
# define EXTERN_INLINE __fastcall
# define EXTERN_INLINE_HEADER extern __fastcall
#endif

#if defined(_MSC_VER)
# define EDUKE32_NORETURN __declspec(noreturn)
#else
# define EDUKE32_NORETURN __attribute__((noreturn))
#endif

#if 1 && defined(__OPTIMIZE__) && (defined __GNUC__ || __has_builtin(__builtin_expect))
# define EDUKE32_PREDICT_TRUE(x)       __builtin_expect(!!(x),1)
# define EDUKE32_PREDICT_FALSE(x)     __builtin_expect(!!(x),0)
#else
# define EDUKE32_PREDICT_TRUE(x) (x)
# define EDUKE32_PREDICT_FALSE(x) (x)
#endif

#ifdef DEBUG
# define EDUKE32_UNREACHABLE_SECTION(...) debug_break()
#else
# if EDUKE32_GCC_PREREQ(4,5)  || __has_builtin(__builtin_unreachable)
#  define EDUKE32_UNREACHABLE_SECTION(...)   __builtin_unreachable()
# elif _MSC_VER
#  define EDUKE32_UNREACHABLE_SECTION(...)   __assume(0)
# else
#  define EDUKE32_UNREACHABLE_SECTION(...) __VA_ARGS__
# endif
#endif
#if EDUKE32_GCC_PREREQ(2,0) || defined _MSC_VER
# define EDUKE32_FUNCTION __FUNCTION__
#elif CSTD >= 1999 || CXXSTD >= 2011
# define EDUKE32_FUNCTION __func__
#else
# define EDUKE32_FUNCTION "???"
#endif

#ifdef _MSC_VER
# define EDUKE32_PRETTY_FUNCTION __FUNCSIG__
#elif EDUKE32_GCC_PREREQ(2,0)
# define EDUKE32_PRETTY_FUNCTION __PRETTY_FUNCTION__
#else
# define EDUKE32_PRETTY_FUNCTION EDUKE32_FUNCTION
#endif

#ifdef __COUNTER__
# define EDUKE32_UNIQUE_SRC_ID __COUNTER__
#else
# define EDUKE32_UNIQUE_SRC_ID __LINE__
#endif

#if CXXSTD >= 2017
# define EDUKE32_STATIC_ASSERT(cond) static_assert(cond)
#elif CXXSTD >= 2011 || CSTD >= 2011 || EDUKE32_MSVC_PREREQ(1600)
# define EDUKE32_STATIC_ASSERT(cond) static_assert(cond, "")
#else
/* C99 / C++03 static assertions based on source found in LuaJIT's src/lj_def.h. */
# define EDUKE32_ASSERT_NAME2(name, line) name ## line
# define EDUKE32_ASSERT_NAME(line) EDUKE32_ASSERT_NAME2(eduke32_assert_, line)
# define EDUKE32_STATIC_ASSERT(cond) \
    extern void EDUKE32_ASSERT_NAME(EDUKE32_UNIQUE_SRC_ID)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
#endif

#ifdef _MSC_VER
# define longlong(x) x##i64
#else
# define longlong(x) x##ll
#endif

#ifndef FP_OFF
# define FP_OFF(__p) ((uintptr_t)(__p))
#endif

#ifdef UNDERSCORES
# define ASMSYM(x) "_" x
#else
# define ASMSYM(x) x
#endif

#if defined __cplusplus
# define STATIC_CAST_OP(t) static_cast<t>
# define REINTERPRET_CAST_OP(t) reinterpret_cast<t>
#else
# define STATIC_CAST_OP(t) (t)
# define REINTERPRET_CAST_OP(t) (t)
#endif
#define STATIC_CAST(t, v) (STATIC_CAST_OP(t)(v))
#define REINTERPRET_CAST(t, v) (REINTERPRET_CAST_OP(t)(v))

#if defined __cplusplus && (__cplusplus >= 201103L || __has_feature(cxx_constexpr) || EDUKE32_MSVC_CXX_PREREQ(1900))
# define HAVE_CONSTEXPR
# define CONSTEXPR constexpr
#else
# define CONSTEXPR
#endif

#if CXXSTD >= 2011 || EDUKE32_MSVC_PREREQ(1700)
# define FINAL final
#else
# define FINAL
#endif

#if CXXSTD >= 2014
# define CONSTEXPR_CXX14 CONSTEXPR
#else
# define CONSTEXPR_CXX14
#endif

#if CXXSTD >= 2011
# if __has_cpp_attribute(fallthrough)
#  define fallthrough__ [[fallthrough]]
# elif __has_cpp_attribute(clang::fallthrough)
#  define fallthrough__ [[clang::fallthrough]]
# elif __has_cpp_attribute(gnu::fallthrough)
#  define fallthrough__ [[gnu::fallthrough]]
# endif
#endif
#ifndef fallthrough__
# if !defined __clang__ && EDUKE32_GCC_PREREQ(7,0)
#  define fallthrough__ __attribute__((fallthrough))
# elif defined _MSC_VER
#  define fallthrough__ __fallthrough
# else
#  define fallthrough__
# endif
#endif

////////// Platform detection //////////

#if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__
# define EDUKE32_BSD
#endif

#ifdef __APPLE__
# include <TargetConditionals.h>
# if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#  define EDUKE32_IOS
# else
#  define EDUKE32_OSX
# endif
#endif

////////// Architecture detection //////////

#if defined __arm__ || defined __aarch64__
# define EDUKE32_CPU_ARM
#elif defined __i386 || defined __i386__ || defined _M_IX86 || defined _M_X64 || defined __x86_64__
# define EDUKE32_CPU_X86
#elif defined _M_PPC || defined __powerpc__ || defined __powerpc64__
# define EDUKE32_CPU_PPC
#elif defined __MIPSEL__ || defined __mips_isa_rev
# define EDUKE32_CPU_MIPS
#endif

#if defined _LP64 || defined __LP64__ || defined __64BIT__ || _ADDR64 || defined _WIN64 || defined __arch64__ ||       \
__WORDSIZE == 64 || (defined __sparc && defined __sparcv9) || defined __x86_64 || defined __amd64 ||                   \
defined __x86_64__ || defined __amd64__ || defined _M_X64 || defined _M_IA64 || defined __ia64 || defined __IA64__

# define BITNESS64

#endif

#if defined(__linux)
# include <endian.h>
# if __BYTE_ORDER == __LITTLE_ENDIAN
#  define B_LITTLE_ENDIAN 1
#  define B_BIG_ENDIAN    0
# elif __BYTE_ORDER == __BIG_ENDIAN
#  define B_LITTLE_ENDIAN 0
#  define B_BIG_ENDIAN    1
# endif

#elif defined(GEKKO) || defined(__ANDROID__)
# define B_LITTLE_ENDIAN 0
# define B_BIG_ENDIAN 1

#elif defined(__OpenBSD__)
# include <machine/endian.h>
# if _BYTE_ORDER == _LITTLE_ENDIAN
#  define B_LITTLE_ENDIAN 1
#  define B_BIG_ENDIAN    0
# elif _BYTE_ORDER == _BIG_ENDIAN
#  define B_LITTLE_ENDIAN 0
#  define B_BIG_ENDIAN    1
# endif

#elif defined EDUKE32_BSD
# include <sys/endian.h>
# if _BYTE_ORDER == _LITTLE_ENDIAN
#  define B_LITTLE_ENDIAN 1
#  define B_BIG_ENDIAN    0
# elif _BYTE_ORDER == _BIG_ENDIAN
#  define B_LITTLE_ENDIAN 0
#  define B_BIG_ENDIAN    1
# endif

#elif defined(__APPLE__)
# if defined(__LITTLE_ENDIAN__)
#  define B_LITTLE_ENDIAN 1
#  define B_BIG_ENDIAN    0
# elif defined(__BIG_ENDIAN__)
#  define B_LITTLE_ENDIAN 0
#  define B_BIG_ENDIAN    1
# endif
# include <libkern/OSByteOrder.h>

#elif defined(__BEOS__)
# include <posix/endian.h>
# if LITTLE_ENDIAN != 0
#  define B_LITTLE_ENDIAN 1
#  define B_BIG_ENDIAN    0
# elif BIG_ENDIAN != 0
#  define B_LITTLE_ENDIAN 0
#  define B_BIG_ENDIAN    1
# endif

#elif defined(__QNX__)
# if defined __LITTLEENDIAN__
#  define B_LITTLE_ENDIAN 1
#  define B_BIG_ENDIAN    0
# elif defined __BIGENDIAN__
#  define B_LITTLE_ENDIAN 0
#  define B_BIG_ENDIAN    1
# endif

#elif defined(__sun)
# if defined _LITTLE_ENDIAN
#  define B_LITTLE_ENDIAN 1
#  define B_BIG_ENDIAN    0
# elif defined _BIG_ENDIAN
#  define B_LITTLE_ENDIAN 0
#  define B_BIG_ENDIAN    1
# endif

#elif defined(_WIN32) || defined(SKYOS) || defined(__SYLLABLE__)
# define B_LITTLE_ENDIAN 1
# define B_BIG_ENDIAN    0
#endif

#if !defined(B_LITTLE_ENDIAN) || !defined(B_BIG_ENDIAN)
# error Unknown endianness
#endif

////////// Standard library headers //////////

#undef __USE_MINGW_ANSI_STDIO // Workaround for MinGW-w64.

#ifndef __STDC_FORMAT_MACROS
# define __STDC_FORMAT_MACROS
#endif
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
#endif

#ifndef _USE_MATH_DEFINES
# define _USE_MATH_DEFINES
#endif

#include <inttypes.h>
#include <stdint.h>

#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#ifndef USE_PHYSFS
#include <stdio.h>
#endif
#include <stdlib.h>
#include <string.h>

#if !(defined _WIN32 && defined __clang__)
#include <float.h>
#endif
#include <math.h>

#include <ctype.h>
#include <errno.h>
#include <time.h>

#include <assert.h>

#ifdef __cplusplus
# include <limits>
# if CXXSTD >= 2011 || EDUKE32_MSVC_PREREQ(1800)
#  include <algorithm>
#  include <functional>
#  include <type_traits>
// we need this because MSVC does not properly identify C++11 support
#  define HAVE_CXX11_HEADERS
# endif
#endif

////////// Platform headers //////////

#ifndef USE_PHYSFS
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#if defined(_WIN32)
# include <direct.h>
# include <io.h>
#else
# include <unistd.h>
#endif
#endif

////////// DEPRECATED: Standard library prefixing //////////

#ifdef _MSC_VER
# if defined _M_AMD64 || defined _M_ARM64 || defined _M_X64 || defined _WIN64
// should be int64_t, if not for a suspected VS compiler bug
typedef int64_t ssize_t;
# else
typedef int32_t ssize_t;
# endif
#endif

typedef size_t bsize_t;
typedef ssize_t bssize_t;

typedef FILE BFILE;

#define BO_BINARY O_BINARY
#define BO_TEXT   O_TEXT
#define BO_RDONLY O_RDONLY
#define BO_WRONLY O_WRONLY
#define BO_RDWR   O_RDWR
#define BO_APPEND O_APPEND
#define BO_CREAT  O_CREAT
#define BO_TRUNC  O_TRUNC
#define BS_IRGRP  S_IRGRP
#define BS_IWGRP  S_IWGRP
#define BS_IEXEC  S_IEXEC
#define BS_IFIFO  S_IFIFO
#define BS_IFCHR  S_IFCHR
#define BS_IFBLK  S_IFBLK
#define BS_IFDIR  S_IFDIR
#define BS_IFREG  S_IFREG
#define BSEEK_SET SEEK_SET
#define BSEEK_CUR SEEK_CUR
#define BSEEK_END SEEK_END

#define BMAX_PATH 256

#define Bassert assert
#define Bmalloc malloc
#define Bcalloc calloc
#define Brealloc realloc
#define Bfree free
#define Bopen open
#define Bclose close
#define Bwrite write
#define Bread read
#define Blseek lseek
#define Bstat stat
#define Bfstat fstat
#define Bfileno fileno
#define Bferror ferror
#define Bfopen fopen
#define Bfclose fclose
#define Bfflush fflush
#define Bfeof feof
#define Bfgetc fgetc
#define Brewind rewind
#define Bfgets fgets
#define Bfputc fputc
#define Bfputs fputs
#define Bfread fread
#define Bfwrite fwrite
#define Bfprintf fprintf
#define Bfscanf fscanf
#define Bfseek fseek
#define Bftell ftell
#define Bputs puts
#define Bstrcpy strcpy
#define Bstrncpy strncpy
#define Bstrcmp strcmp
#define Bstrncmp strncmp
#define Bstrcat strcat
#define Bstrncat strncat
#define Bstrlen strlen
#define Bstrchr strchr
#define Bstrrchr strrchr
#define Bstrtol strtol
#define Bstrtoul strtoul
#define Bstrtod strtod
#define Bstrstr strstr
#define Bislower islower
#define Bisupper isupper
#define Bisdigit isdigit
#define Btoupper toupper
#define Btolower tolower
#define Bmemcpy memcpy
#define Bmemmove memmove
#define Bmemchr memchr
#define Bmemset memset
#define Bmemcmp memcmp
#define Bscanf scanf
#define Bprintf printf
#define Bsscanf sscanf
#define Bsprintf sprintf
#define Bvfprintf vfprintf
#define Bgetenv getenv
#define Butime utime

////////// Standard library wrappers //////////

#ifdef __ANDROID__
# define BS_IWRITE S_IWUSR
# define BS_IREAD  S_IRUSR
#else
# define BS_IWRITE S_IWRITE
# define BS_IREAD  S_IREAD
#endif

#if defined(__cplusplus) && defined(_MSC_VER)
# define Bstrdup _strdup
# define Bchdir _chdir
# define Bgetcwd _getcwd
#else
# define Bstrdup strdup
# define Bchdir chdir
# define Bgetcwd getcwd
#endif

#if defined(__GNUC__)
# define Btell(h) lseek(h,0,SEEK_CUR)
#else
# define Btell tell
#endif

#if defined(_MSC_VER)
# define Bstrcasecmp _stricmp
# define Bstrncasecmp _strnicmp
#elif defined(__QNX__)
# define Bstrcasecmp stricmp
# define Bstrncasecmp strnicmp
#else
# define Bstrcasecmp strcasecmp
# define Bstrncasecmp strncasecmp
#endif

#ifdef _WIN32
# define Bsnprintf _snprintf
# define Bvsnprintf _vsnprintf
#else
# define Bsnprintf snprintf
# define Bvsnprintf vsnprintf
#endif

#ifdef _MSC_VER
# define Balloca _alloca
#elif defined __GNUC__
# define Balloca __builtin_alloca
#else
# define Balloca alloca
#endif

#ifdef _MSC_VER
# define Bmalloca _malloca
# define Bfreea _freea
#else
# define Bmalloca alloca
# define Bfreea(ptr) do { } while (0)
#endif

#define Btime() time(NULL)

#if defined(_WIN32)
# define Bmkdir(s,x) mkdir(s)
#else
# define Bmkdir mkdir
#endif

// XXX: different across 32- and 64-bit archs (e.g.
// parsing the decimal representation of 0xffffffff,
// 4294967295 -- long is signed, so strtol would
// return LONG_MAX (== 0x7fffffff on 32-bit archs))

static FORCE_INLINE int32_t atoi_safe(const char *str) { return (int32_t)Bstrtol(str, NULL, 10); }

#define Batoi(x) atoi_safe(x)
#define Batol(str) (strtol(str, NULL, 10))
#define Batof(str) (strtod(str, NULL))

#if defined BITNESS64 && (defined __SSE2__ || defined _MSC_VER) && !defined(_M_ARM64)
#include <emmintrin.h>
static FORCE_INLINE int32_t Blrintf(const float x)
{
    __m128 xx = _mm_load_ss(&x);
    return _mm_cvtss_si32(xx);
}
#elif defined(_MSC_VER) && !defined(_M_ARM64)
static FORCE_INLINE int32_t Blrintf(const float x)
{
    int n;
    __asm fld x;
    __asm fistp n;
    return n;
}
#else
#define Blrintf(x) ((int32_t)lrintf(x))
#endif

#if defined(__arm__)
# define Bsqrt __builtin_sqrt
# define Bsqrtf __builtin_sqrtf
#else
# define Bsqrt sqrt
# define Bsqrtf sqrtf
#endif

// redefined for apple/ppc, which chokes on stderr when linking...
#if defined EDUKE32_OSX && defined __BIG_ENDIAN__
# define ERRprintf(fmt, ...) printf(fmt, ## __VA_ARGS__)
#else
# define ERRprintf(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
#endif

#ifdef __ANDROID__
void eduke32_exit_return(int) ATTRIBUTE((noreturn));
# define exit(x) eduke32_exit_return(x)
#endif

#ifdef DEBUGGINGAIDS
#define Bexit(status)                                                                            \
    do                                                                                \
    {                                                                                \
        initprintf("exit(%d) at %s:%d in %s()\n", status, __FILE__, __LINE__, EDUKE32_FUNCTION); \
        engineDestroyAllocator();                                                                \
        exit(status);                                                                            \
    } while (0)
#else
# define Bexit(status) do { engineDestroyAllocator(); exit(status); } while (0)
#endif

// do not try and wrap fatal_exit inside another function or you will break its functionality (obviously...)
#ifdef _WIN32
#define fatal_exit__(x) FatalAppExitA(0, x)
#else
#define fatal_exit__(x) do { wm_msgbox("Fatal Error", "%s", x); exit(EXIT_FAILURE); } while(0)
#endif

#define fatal_exit(status)                                                                             \
    do                                                                                \
    {                                                                                \
        initprintf("fatal_exit(%s) at %s:%d in %s()\n", status, __FILE__, __LINE__, EDUKE32_FUNCTION); \
        engineDestroyAllocator();                                                                      \
        fatal_exit__(status);                                                                          \
    } while (0)

////////// Standard library monkey patching //////////

#ifndef NULL
# define NULL ((void *)0)
#endif

#ifdef _MSC_VER
# define strtoll _strtoi64
#endif

#ifndef O_BINARY
# define O_BINARY 0
#endif
#ifndef O_TEXT
# define O_TEXT 0
#endif

#ifndef F_OK
# define F_OK 0
#endif

#ifdef GEKKO
# undef PRIdPTR
# define PRIdPTR "d"
# undef PRIxPTR
# define PRIxPTR "x"
# undef SCNx32
# define SCNx32 "x"
#endif

#if defined EDUKE32_OSX
# if !defined __x86_64__ && defined __GNUC__
// PK 20110617: is*() crashes for me in x86 code compiled from 64-bit, and gives link errors on ppc
//              This hack patches all occurences.
#  define isdigit(ch) ({ int32_t c__dontuse_=ch; c__dontuse_>='0' && c__dontuse_<='9'; })
#  define isalpha(ch) ({ int32_t c__dontuse2_=ch; (c__dontuse2_>='A' && c__dontuse2_<='Z') || (c__dontuse2_>='a' && c__dontuse2_<='z'); })
#  define isalnum(ch2)  ({ int32_t c2__dontuse_=ch2; isalpha(c2__dontuse_) || isdigit(c2__dontuse_); })
#  if defined __BIG_ENDIAN__
#   define isspace(ch)  ({ int32_t c__dontuse_=ch; (c__dontuse_==' ' || c__dontuse_=='\t' || c__dontuse_=='\n' || c__dontuse_=='\v' || c__dontuse_=='\f' || c__dontuse_=='\r'); })
#   define isprint(ch)  ({ int32_t c__dontuse_=ch; (c__dontuse_>=0x20 && c__dontuse_<0x7f); })
#  endif
# endif
#endif

////////// Metaprogramming structs //////////

#ifdef __cplusplus

# ifdef HAVE_CXX11_HEADERS
using std::is_integral;
template <typename T>
struct is_signed
{
    static constexpr bool value = std::is_signed<T>::value;
};
template <typename T>
struct is_unsigned
{
    static constexpr bool value = std::is_unsigned<T>::value;
};
# endif

# if CXXSTD >= 2014
using std::enable_if_t;
using std::conditional_t;
using std::make_signed_t;
using std::make_unsigned_t;
using std::remove_pointer_t;
# elif defined HAVE_CXX11_HEADERS
template <bool B, class T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
template<bool B, class T, class F>
using conditional_t = typename std::conditional<B, T, F>::type;
template <typename T>
using make_signed_t = typename std::make_signed<T>::type;
template <typename T>
using make_unsigned_t = typename std::make_unsigned<T>::type;
template <class T>
using remove_pointer_t = typename std::remove_pointer<T>::type;
# endif

# ifdef HAVE_CXX11_HEADERS
template <typename type, typename other_type_with_sign>
using take_sign_t = conditional_t< is_signed<other_type_with_sign>::value, make_signed_t<type>, make_unsigned_t<type> >;
# endif

template <size_t size>
struct integers_of_size { };
template <>
struct integers_of_size<sizeof(int8_t)>
{
    typedef int8_t i;
    typedef uint8_t u;
};
template <>
struct integers_of_size<sizeof(int16_t)>
{
    typedef int16_t i;
    typedef uint16_t u;
};
template <>
struct integers_of_size<sizeof(int32_t)>
{
    typedef int32_t i;
    typedef uint32_t u;
};
template <>
struct integers_of_size<sizeof(int64_t)>
{
    typedef int64_t i;
    typedef uint64_t u;
};

#endif

////////// Typedefs //////////

#ifdef __cplusplus
// for use in SFINAE constructs in place of the pointer trick (to which 0 can unintentionally be implicitly cast)
struct Dummy FINAL
{
    FORCE_INLINE CONSTEXPR Dummy() : dummy(0) { }
    char dummy;
};
#endif

#if defined(__x86_64__)
// for 32-bit pointers in x86_64 code, such as `gcc -mx32`
typedef uint64_t reg_t;
typedef int64_t sreg_t;
#else
typedef size_t reg_t;
typedef ssize_t sreg_t;
#endif

#ifdef HAVE_CXX11_HEADERS
using  native_t = typename integers_of_size<sizeof(reg_t)>::i;
using unative_t = typename integers_of_size<sizeof(reg_t)>::u;
#else
typedef sreg_t native_t;
typedef reg_t unative_t;
#endif
EDUKE32_STATIC_ASSERT(sizeof(native_t) == sizeof(unative_t));

////////// Language tricks that depend on size_t //////////

#if defined _MSC_VER
# define ARRAY_SIZE(arr) _countof(arr)
#elif defined HAVE_CONSTEXPR
template <typename T, size_t N>
static FORCE_INLINE constexpr size_t ARRAY_SIZE(T const (&)[N]) noexcept
{
    return N;
}
#elif defined __cplusplus
struct bad_arg_to_ARRAY_SIZE
{
   class Is_pointer; // incomplete
   class Is_array {};
   template <typename T>
   static Is_pointer check_type(const T*, const T* const*);
   static Is_array check_type(const void*, const void*);
};
# define ARRAY_SIZE(arr) ( \
   0 * sizeof(reinterpret_cast<const ::bad_arg_to_ARRAY_SIZE*>(arr)) + \
   0 * sizeof(::bad_arg_to_ARRAY_SIZE::check_type((arr), &(arr))) + \
   sizeof(arr) / sizeof((arr)[0]) )
#else
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#define ARRAY_SSIZE(arr) (native_t)ARRAY_SIZE(arr)

////////// Pointer management //////////

#define DO_FREE_AND_NULL(var) do { \
    Xfree(var); (var) = nullptr; \
} while (0)

#define ALIGNED_FREE_AND_NULL(var) do { \
    Xaligned_free(var); (var) = nullptr; \
} while (0)

#define DO_DELETE_AND_NULL(var) do { \
    delete (var); (var) = nullptr; \
} while (0)

////////// Data serialization //////////

static FORCE_INLINE CONSTEXPR uint16_t B_SWAP16_impl(uint16_t value)
{
    return
        ((value & 0xFF00u) >> 8u) |
        ((value & 0x00FFu) << 8u);
}
static FORCE_INLINE CONSTEXPR uint32_t B_SWAP32_impl(uint32_t value)
{
    return
        ((value & 0xFF000000u) >> 24u) |
        ((value & 0x00FF0000u) >>  8u) |
        ((value & 0x0000FF00u) <<  8u) |
        ((value & 0x000000FFu) << 24u);
}
static FORCE_INLINE CONSTEXPR uint64_t B_SWAP64_impl(uint64_t value)
{
    return
      ((value & 0xFF00000000000000ULL) >> 56ULL) |
      ((value & 0x00FF000000000000ULL) >> 40ULL) |
      ((value & 0x0000FF0000000000ULL) >> 24ULL) |
      ((value & 0x000000FF00000000ULL) >>  8ULL) |
      ((value & 0x00000000FF000000ULL) <<  8ULL) |
      ((value & 0x0000000000FF0000ULL) << 24ULL) |
      ((value & 0x000000000000FF00ULL) << 40ULL) |
      ((value & 0x00000000000000FFULL) << 56ULL);
}

/* The purpose of B_PASS* as functions, as opposed to macros, is to prevent them from being used as lvalues. */
#if defined __cplusplus && (CXXSTD >= 2011 || EDUKE32_MSVC_CXX_PREREQ(1900))
template <typename T>
static FORCE_INLINE CONSTEXPR take_sign_t<int16_t, T> B_SWAP16(T x)
{
    return static_cast< take_sign_t<int16_t, T> >(B_SWAP16_impl(static_cast<uint16_t>(x)));
}
template <typename T>
static FORCE_INLINE CONSTEXPR take_sign_t<int32_t, T> B_SWAP32(T x)
{
    return static_cast< take_sign_t<int32_t, T> >(B_SWAP32_impl(static_cast<uint32_t>(x)));
}
template <typename T>
static FORCE_INLINE CONSTEXPR take_sign_t<int64_t, T> B_SWAP64(T x)
{
    return static_cast< take_sign_t<int64_t, T> >(B_SWAP64_impl(static_cast<uint64_t>(x)));
}

template <typename T>
static FORCE_INLINE CONSTEXPR take_sign_t<int16_t, T> B_PASS16(T x)
{
    return static_cast< take_sign_t<int16_t, T> >(x);
}
template <typename T>
static FORCE_INLINE CONSTEXPR take_sign_t<int32_t, T> B_PASS32(T x)
{
    return static_cast< take_sign_t<int32_t, T> >(x);
}
template <typename T>
static FORCE_INLINE CONSTEXPR take_sign_t<int64_t, T> B_PASS64(T x)
{
    return static_cast< take_sign_t<int64_t, T> >(x);
}
#else
#define B_SWAP16(x) B_SWAP16_impl(x)
#define B_SWAP32(x) B_SWAP32_impl(x)
#define B_SWAP64(x) B_SWAP64_impl(x)

static FORCE_INLINE CONSTEXPR uint16_t B_PASS16(uint16_t const x) { return x; }
static FORCE_INLINE CONSTEXPR uint32_t B_PASS32(uint32_t const x) { return x; }
static FORCE_INLINE CONSTEXPR uint64_t B_PASS64(uint64_t const x) { return x; }
#endif

#if B_LITTLE_ENDIAN == 1
# define B_LITTLE64(x) B_PASS64(x)
# define B_BIG64(x)    B_SWAP64(x)
# define B_LITTLE32(x) B_PASS32(x)
# define B_BIG32(x)    B_SWAP32(x)
# define B_LITTLE16(x) B_PASS16(x)
# define B_BIG16(x)    B_SWAP16(x)
#elif B_BIG_ENDIAN == 1
# define B_LITTLE64(x) B_SWAP64(x)
# define B_BIG64(x)    B_PASS64(x)
# define B_LITTLE32(x) B_SWAP32(x)
# define B_BIG32(x)    B_PASS32(x)
# define B_LITTLE16(x) B_SWAP16(x)
# define B_BIG16(x)    B_PASS16(x)
#endif

// TODO: Determine when, if ever, we should use the bit-shift-and-mask variants
// due to alignment issues or performance gains.
#if 1
static FORCE_INLINE void B_BUF16(void * const buf, uint16_t const x) { *(uint16_t *) buf = x; }
static FORCE_INLINE void B_BUF32(void * const buf, uint32_t const x) { *(uint32_t *) buf = x; }
static FORCE_INLINE void B_BUF64(void * const buf, uint64_t const x) { *(uint64_t *) buf = x; }

static FORCE_INLINE CONSTEXPR uint16_t B_UNBUF16(void const * const buf) { return *(uint16_t const *) buf; }
static FORCE_INLINE CONSTEXPR uint32_t B_UNBUF32(void const * const buf) { return *(uint32_t const *) buf; }
static FORCE_INLINE CONSTEXPR uint64_t B_UNBUF64(void const * const buf) { return *(uint64_t const *) buf; }
#else
static FORCE_INLINE void B_BUF16(void * const vbuf, uint16_t const x)
{
    uint8_t * const buf = (uint8_t *) vbuf;
    buf[0] = (x & 0x00FF);
    buf[1] = (x & 0xFF00) >> 8;
}
static FORCE_INLINE void B_BUF32(void * const vbuf, uint32_t const x)
{
    uint8_t * const buf = (uint8_t *) vbuf;
    buf[0] = (x & 0x000000FF);
    buf[1] = (x & 0x0000FF00) >> 8;
    buf[2] = (x & 0x00FF0000) >> 16;
    buf[3] = (x & 0xFF000000) >> 24;
}
# if 0
// i686-apple-darwin11-llvm-gcc-4.2 complains "integer constant is too large for 'long' type"
static FORCE_INLINE void B_BUF64(void * const vbuf, uint64_t const x)
{
    uint8_t * const buf = (uint8_t *) vbuf;
    buf[0] = (x & 0x00000000000000FF);
    buf[1] = (x & 0x000000000000FF00) >> 8;
    buf[2] = (x & 0x0000000000FF0000) >> 16;
    buf[3] = (x & 0x00000000FF000000) >> 24;
    buf[4] = (x & 0x000000FF00000000) >> 32;
    buf[5] = (x & 0x0000FF0000000000) >> 40;
    buf[6] = (x & 0x00FF000000000000) >> 48;
    buf[7] = (x & 0xFF00000000000000) >> 56;
}
# endif

static FORCE_INLINE uint16_t B_UNBUF16(void const * const vbuf)
{
    uint8_t const * const buf = (uint8_t const *) vbuf;
    return (buf[1] << 8) | (buf[0]);
}
static FORCE_INLINE uint32_t B_UNBUF32(void const * const vbuf)
{
    uint8_t const * const buf = (uint8_t const *) vbuf;
    return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]);
}
static FORCE_INLINE uint64_t B_UNBUF64(void const * const vbuf)
{
    uint8_t const * const buf = (uint8_t const *) vbuf;
    return ((uint64_t)buf[7] << 56) | ((uint64_t)buf[6] << 48) | ((uint64_t)buf[5] << 40) |
        ((uint64_t)buf[4] << 32) | (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]);
}
#endif

////////// Abstract data operations //////////

#define ABSTRACT_DECL static FORCE_INLINE WARN_UNUSED_RESULT CONSTEXPR

#ifdef __cplusplus
template <typename T, typename X, typename Y> ABSTRACT_DECL T clamp(T in, X min, Y max) { return in <= (T) min ? (T) min : (in >= (T) max ? (T) max : in); }
template <typename T, typename X, typename Y> ABSTRACT_DECL T clamp2(T in, X min, Y max) { return in >= (T) max ? (T) max : (in <= (T) min ? (T) min : in); }
using std::min;
using std::max;
# define fclamp clamp
# define fclamp2 clamp2
#else
// Clamp <in> to [<min>..<max>]. The case in <= min is handled first.
ABSTRACT_DECL int32_t clamp(int32_t in, int32_t min, int32_t max) { return in <= min ? min : (in >= max ? max : in); }
ABSTRACT_DECL float fclamp(float in, float min, float max) { return in <= min ? min : (in >= max ? max : in); }
// Clamp <in> to [<min>..<max>]. The case in >= max is handled first.
ABSTRACT_DECL int32_t clamp2(int32_t in, int32_t min, int32_t max) { return in >= max ? max : (in <= min ? min : in); }
ABSTRACT_DECL float fclamp2(float in, float min, float max) { return in >= max ? max : (in <= min ? min : in); }

#ifndef min
# define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
# define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#endif

////////// Mathematical operations //////////

#ifdef __cplusplus
#ifdef HAVE_CXX11_HEADERS
template <typename T>
struct DivResult
{
    T q; // quotient
    T r; // remainder
};
template <typename T>
FORCE_INLINE CONSTEXPR DivResult<T> divide(T lhs, T rhs)
{
    return DivResult<T>{(T)(lhs / rhs), (T)(lhs % rhs)};
}
template <native_t base, typename T>
FORCE_INLINE CONSTEXPR DivResult<T> divrhs(T lhs)
{
    return divide(lhs, (T)base);
}

template <typename T, typename T2>
static FORCE_INLINE CONSTEXPR_CXX14 enable_if_t<is_signed<T>::value, T> NEGATE_ON_CONDITION(T value, T2 condition)
{
    T const invert = !!condition;
    return (value ^ -invert) + invert;
}
#endif

template <size_t base, typename T>
CONSTEXPR size_t logbase(T n)
{
    return n < static_cast<T>(base) ? 1 : 1 + logbase<base>(n / static_cast<T>(base));
}
// hackish version to work around the impossibility of representing abs(INT*_MIN)
template <size_t base, typename T>
CONSTEXPR size_t logbasenegative(T n)
{
    return n > static_cast<T>(-(native_t)base) ? 1 : 1 + logbase<base>(n / static_cast<T>(-(native_t)base));
}

#endif

#define isPow2OrZero(v) (((v) & ((v) - 1)) == 0)
#define isPow2(v) (isPow2OrZero(v) && (v))

static FORCE_INLINE int nextPow2(int const value)
{
    int i = 1;
    while (i < value)
        i <<= 1;
    return i;
}

////////// Bitfield manipulation //////////

static CONSTEXPR const char pow2char[8] = {1,2,4,8,16,32,64,128u};

#ifdef __cplusplus
template <typename T>
static FORCE_INLINE void bitmap_set(T *const ptr, int const n)
{
    EDUKE32_STATIC_ASSERT((sizeof(T) << 3) == CHAR_BIT);
    ptr[n>>3] |= pow2char[n&7];
}

template <typename T>
static FORCE_INLINE void bitmap_clear(T *const ptr, int const n)
{
    EDUKE32_STATIC_ASSERT((sizeof(T) << 3) == CHAR_BIT);
    ptr[n>>3] &= ~pow2char[n&7];
}

template <typename T>
static FORCE_INLINE CONSTEXPR bool bitmap_test(T const *const ptr, int const n)
{
    EDUKE32_STATIC_ASSERT((sizeof(T) << 3) == CHAR_BIT);
    return (ptr[n>>3] & pow2char[n&7]) == pow2char[n&7];
}

////////// Utility functions //////////

// breadth-first search helpers
template <typename T>
void bfirst_search_init(T *const list, uint8_t *const bitmap, T *const eltnumptr, int const maxelts, int const firstelt)
{
    Bmemset(bitmap, 0, (maxelts+7)>>3);

    list[0] = firstelt;
    bitmap_set(bitmap, firstelt);
    *eltnumptr = 1;
}

template <typename T>
void bfirst_search_try(T *const list, uint8_t *const bitmap, T *const eltnumptr, int const elt)
{
    if (!bitmap_test(bitmap, elt))
    {
        bitmap_set(bitmap, elt);
        list[(*eltnumptr)++] = elt;
    }
}
#endif

#if RAND_MAX == 32767
static FORCE_INLINE uint16_t system_15bit_rand(void) { return (uint16_t)rand(); }
#else  // RAND_MAX > 32767, assumed to be of the form 2^k - 1
static FORCE_INLINE uint16_t system_15bit_rand(void) { return ((uint16_t)rand())&0x7fff; }
#endif

// Copy min(strlen(src)+1, n) characters into dst, always terminate with a NUL.
static FORCE_INLINE char *Bstrncpyz(char *dst, const char *src, bsize_t n)
{
    if (n > 0)
    {
        Bmemcpy(dst, src, min(Bstrlen(src)+1, n-1));
        dst[n-1] = '\0';
    }

    return dst;
}

// Append extension when <outbuf> contains no dot.
// <ext> can be like ".mhk" or like "_crash.map", no need to start with a dot.
// The ugly name is deliberate: we should be checking the sizes of all buffers!
static inline void append_ext_UNSAFE(char *outbuf, const char *ext)
{
    char *p = Bstrrchr(outbuf,'.');

    if (!p)
        Bstrcat(outbuf, ext);
    else
        Bstrcpy(p, ext);
}

/* Begin dependence on compat.o object. */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef USE_PHYSFS
////////// Directory enumeration //////////

struct Bdirent
{
    char *name;
    uint32_t mode;
    uint32_t size;
    uint32_t mtime;
    uint16_t namlen;
};

typedef void BDIR;

BDIR *Bopendir(const char *name);
struct Bdirent *Breaddir(BDIR *dir);
int32_t Bclosedir(BDIR *dir);
#endif

////////// Paths //////////

char *Bgethomedir(void);
char *Bgetappdir(void);

int32_t Bcorrectfilename(char *filename, int32_t removefn);
int32_t Bcanonicalisefilename(char *filename, int32_t removefn);

char *Bgetsystemdrives(void);

////////// String manipulation //////////

char *Bstrtoken(char *s, const char *delim, char **ptrptr, int chop);
char *Bstrtolower(char *str);

#define Bwildmatch wildmatch

#ifdef _WIN32
# ifdef _MSC_VER
#  define Bstrlwr _strlwr
#  define Bstrupr _strupr
# else
#  define Bstrlwr strlwr
#  define Bstrupr strupr
# endif
#else
char *Bstrlwr(char *);
char *Bstrupr(char *);
#endif

////////// Miscellaneous //////////

int Bgetpagesize(void);
size_t Bgetsysmemsize(void);

#ifdef __cplusplus
}
#endif

////////// Memory management //////////

#ifdef DEBUGGINGAIDS
#ifdef __cplusplus
extern "C"
{
#endif
extern const char *g_MemErrFunc;
extern const char *g_MemErrFile;
extern int32_t g_MemErrLine;
#ifdef __cplusplus
}
#endif

static FORCE_INLINE void xalloc_set_location(int32_t const line, const char * const file, const char * const func)
{
    g_MemErrLine = line;
    g_MemErrFile = file;

    if (func)
        g_MemErrFunc = func;
}
#endif

void set_memerr_handler(void (*handlerfunc)(int32_t, const char *, const char *));
EDUKE32_NORETURN void handle_memerr(void);

#ifdef __cplusplus
#include "smmalloc.h"

extern sm_allocator g_sm_heap;

static FORCE_INLINE void engineCreateAllocator(void)
{
    // 8 buckets of 2MB each--we don't really need to burn a lot of memory here for this thing to do its job
    g_sm_heap = _sm_allocator_create(SMM_MAX_BUCKET_COUNT, 2097152);
    _sm_allocator_thread_cache_create(g_sm_heap, sm::CACHE_HOT, { 20480, 32768, 32768, 1536, 4096, 8192, 128, 4096 });
}

static FORCE_INLINE void engineDestroyAllocator(void)
{
    _sm_allocator_thread_cache_destroy(g_sm_heap);
    _sm_allocator_destroy(g_sm_heap);
}

#ifdef BITNESS64
# define ALLOC_ALIGNMENT 16
#else
# define ALLOC_ALIGNMENT 8
#endif

static FORCE_INLINE char *xstrdup(const char *s)
{
    int const len = Bstrlen(s)+1;
    char *ptr = (char *)_sm_malloc(g_sm_heap, len, ALLOC_ALIGNMENT);
    if (EDUKE32_PREDICT_TRUE(ptr != nullptr))
    {
        Bstrcpy(ptr, s);
        ptr[len-1] = '\0';
        return ptr;
    }
    handle_memerr();
    EDUKE32_UNREACHABLE_SECTION(return nullptr);
}

static FORCE_INLINE void *xmalloc(bsize_t const size)
{
    void *ptr = _sm_malloc(g_sm_heap, size, ALLOC_ALIGNMENT);
    if (EDUKE32_PREDICT_TRUE(ptr != nullptr)) return ptr;
    handle_memerr();
    EDUKE32_UNREACHABLE_SECTION(return nullptr);
}

static FORCE_INLINE void *xcalloc(bsize_t const nmemb, bsize_t const size)
{
    bsize_t const siz = nmemb * size;
    void *ptr = _sm_malloc(g_sm_heap, siz, ALLOC_ALIGNMENT);
    if (EDUKE32_PREDICT_TRUE(ptr != nullptr))
    {
        Bmemset(ptr, 0, siz);
        return ptr;
    }
    handle_memerr();
    EDUKE32_UNREACHABLE_SECTION(return nullptr);
}

static FORCE_INLINE void *xrealloc(void * const ptr, bsize_t const size)
{
    void *newptr = _sm_realloc(g_sm_heap, ptr, size, ALLOC_ALIGNMENT);

    // According to the C Standard,
    //  - ptr == NULL makes realloc() behave like malloc()
    //  - size == 0 make it behave like free() if ptr != NULL
    // Since we want to catch an out-of-mem in the first case, this leaves:
    if (EDUKE32_PREDICT_TRUE(newptr != nullptr || size == 0)) return newptr;
    handle_memerr();
    EDUKE32_UNREACHABLE_SECTION(return nullptr);
}

#undef ALLOC_ALIGNMENT

static FORCE_INLINE void *xaligned_alloc(bsize_t const alignment, bsize_t const size)
{
    void *ptr = _sm_malloc(g_sm_heap, size, alignment);
    if (EDUKE32_PREDICT_TRUE(ptr != nullptr)) return ptr;
    handle_memerr();
    EDUKE32_UNREACHABLE_SECTION(return nullptr);
}

static FORCE_INLINE void *xaligned_calloc(bsize_t const alignment, bsize_t const count, bsize_t const size)
{
    bsize_t const blocksize = count * size;
    void *ptr = _sm_malloc(g_sm_heap, blocksize, alignment);
    if (EDUKE32_PREDICT_TRUE(ptr != nullptr))
    {
        Bmemset(ptr, 0, blocksize);
        return ptr;
    }
    handle_memerr();
    EDUKE32_UNREACHABLE_SECTION(return nullptr);
}

static FORCE_INLINE void xfree(void *const ptr) { _sm_free(g_sm_heap, ptr); }
static FORCE_INLINE void xaligned_free(void *const ptr) { _sm_free(g_sm_heap, ptr); }
#endif

// jump through hoops so stuff with C linkage works
#ifdef __cplusplus
# define _EDUKE32_ALLOC(a) a
#else
# define _EDUKE32_ALLOC(a) _ ## a
#endif

#ifdef DEBUGGINGAIDS
# define EDUKE32_ALLOC_DEBUG xalloc_set_location(__LINE__, __FILE__, EDUKE32_FUNCTION),
# define EDUKE32_ALLOC(x) (EDUKE32_ALLOC_DEBUG _EDUKE32_ALLOC(x))
#else
# define EDUKE32_ALLOC(x) _EDUKE32_ALLOC(x)
#endif

#ifdef __cplusplus
extern "C"
{
#endif
char *_xstrdup(const char *s);
void *_xmalloc(bsize_t const size);
void *_xcalloc(bsize_t const nmemb, bsize_t const size);
void *_xrealloc(void * const ptr, bsize_t const size);
void  _xfree(void * const ptr);
void *_xaligned_alloc(bsize_t const alignment, bsize_t const size);
void *_xaligned_calloc(bsize_t const alignment, bsize_t const count, bsize_t const size);
void  _xaligned_free(void * const ptr);
#ifdef __cplusplus
}
#endif

#define Xstrdup       EDUKE32_ALLOC(xstrdup)
#define Xmalloc       EDUKE32_ALLOC(xmalloc)
#define Xcalloc       EDUKE32_ALLOC(xcalloc)
#define Xrealloc      EDUKE32_ALLOC(xrealloc)
#define Xfree         _EDUKE32_ALLOC(xfree)
#define Xaligned_free _EDUKE32_ALLOC(xaligned_free)

#define Xaligned_alloc  EDUKE32_ALLOC(xaligned_alloc)
#define Xaligned_calloc EDUKE32_ALLOC(xaligned_calloc)

////////// More utility functions //////////

static inline void maybe_grow_buffer(char ** const buffer, int32_t * const buffersize, int32_t const newsize)
{
    if (newsize > *buffersize)
    {
        *buffer = (char *)Xrealloc(*buffer, newsize);
        *buffersize = newsize;
    }
}

#include "vec.h"

////////// Inlined external libraries //////////

#include "libdivide_config.h"
#include "fix16.h"

#ifdef __cplusplus
#include "clockticks.hpp"
#endif

#include "debugbreak.h"
#include "rdtsc.h"

/* End dependence on compat.o object. */

////////// EDuke32-specific features //////////

#ifndef TRUE
# define TRUE 1
#endif

#ifndef FALSE
# define FALSE 0
#endif

#define WITHKPLIB

#if defined __ANDROID__ || defined EDUKE32_IOS
# define EDUKE32_TOUCH_DEVICES
# define EDUKE32_GLES
#endif

#if DEBUGGINGAIDS>=2
# define DEBUG_MAIN_ARRAYS
#endif

#if !defined DEBUG_MAIN_ARRAYS
# define HAVE_CLIPSHAPE_FEATURE
#endif

#endif // compat_h_


code:
#ifndef crc32_h_
#define crc32_h_

#include "compat.h"

#ifdef __cplusplus
extern "C" {
#endif

#define POLY 0xEDB88320

#ifdef BITNESS64
extern uint32_t crc32table[8][256];
#else
extern uint32_t crc32table[4][256];
#endif

extern uint32_t Bcrc32(const void* data, int length, uint32_t crc);
extern void initcrc32table(void);

#ifdef __cplusplus
}
#endif

#endif

repo_name: orochi/nblood

license: mit


code:
/* Copyright (c) 2011-2021, Scott Tsai
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef DEBUG_BREAK_H
#define DEBUG_BREAK_H

#ifdef _MSC_VER

__forceinline static void debug_break(void) { if (IsDebuggerPresent()) __debugbreak(); }

#else

#ifdef __cplusplus
extern "C" {
#endif

#define DEBUG_BREAK_USE_TRAP_INSTRUCTION 1
#define DEBUG_BREAK_USE_BULTIN_TRAP      2
#define DEBUG_BREAK_USE_SIGTRAP          3

#if defined(__i386__) || defined(__x86_64__)
	#define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION
__inline__ static void trap_instruction(void)
{
#ifdef _WIN32
	if (IsDebuggerPresent())
#endif
	__asm__ volatile("int $0x03");
}
#elif defined(__thumb__)
	#define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION
/* FIXME: handle __THUMB_INTERWORK__ */
__attribute__((always_inline))
__inline__ static void trap_instruction(void)
{
	/* See 'arm-linux-tdep.c' in GDB source.
	 * Both instruction sequences below work. */
#if 1
	/* 'eabi_linux_thumb_le_breakpoint' */
	__asm__ volatile(".inst 0xde01");
#else
	/* 'eabi_linux_thumb2_le_breakpoint' */
	__asm__ volatile(".inst.w 0xf7f0a000");
#endif

	/* Known problem:
	 * After a breakpoint hit, can't 'stepi', 'step', or 'continue' in GDB.
	 * 'step' would keep getting stuck on the same instruction.
	 *
	 * Workaround: use the new GDB commands 'debugbreak-step' and
	 * 'debugbreak-continue' that become available
	 * after you source the script from GDB:
	 *
	 * $ gdb -x debugbreak-gdb.py <... USUAL ARGUMENTS ...>
	 *
	 * 'debugbreak-step' would jump over the breakpoint instruction with
	 * roughly equivalent of:
	 * (gdb) set $instruction_len = 2
	 * (gdb) tbreak *($pc + $instruction_len)
	 * (gdb) jump   *($pc + $instruction_len)
	 */
}
#elif defined(__arm__) && !defined(__thumb__)
	#define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION
__attribute__((always_inline))
__inline__ static void trap_instruction(void)
{
	/* See 'arm-linux-tdep.c' in GDB source,
	 * 'eabi_linux_arm_le_breakpoint' */
	__asm__ volatile(".inst 0xe7f001f0");
	/* Known problem:
	 * Same problem and workaround as Thumb mode */
}
#elif defined(__aarch64__) && defined(__APPLE__)
	#define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_BULTIN_DEBUGTRAP
#elif defined(__aarch64__)
	#define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION
__attribute__((always_inline))
__inline__ static void trap_instruction(void)
{
	/* See 'aarch64-tdep.c' in GDB source,
	 * 'aarch64_default_breakpoint' */
	__asm__ volatile(".inst 0xd4200000");
}
#elif defined(__powerpc__)
	/* PPC 32 or 64-bit, big or little endian */
	#define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION
__attribute__((always_inline))
__inline__ static void trap_instruction(void)
{
	/* See 'rs6000-tdep.c' in GDB source,
	 * 'rs6000_breakpoint' */
	__asm__ volatile(".4byte 0x7d821008");

	/* Known problem:
	 * After a breakpoint hit, can't 'stepi', 'step', or 'continue' in GDB.
	 * 'step' stuck on the same instruction ("twge r2,r2").
	 *
	 * The workaround is the same as ARM Thumb mode: use debugbreak-gdb.py
	 * or manually jump over the instruction. */
}
#elif defined(__riscv)
	/* RISC-V 32 or 64-bit, whether the "C" extension
	 * for compressed, 16-bit instructions are supported or not */
	#define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_TRAP_INSTRUCTION
__attribute__((always_inline))
__inline__ static void trap_instruction(void)
{
	/* See 'riscv-tdep.c' in GDB source,
	 * 'riscv_sw_breakpoint_from_kind' */
	__asm__ volatile(".4byte 0x00100073");
}
#else
	#define DEBUG_BREAK_IMPL DEBUG_BREAK_USE_SIGTRAP
#endif

#ifndef DEBUG_BREAK_IMPL
#error "debugbreak.h is not supported on this target"
#elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_TRAP_INSTRUCTION
__attribute__((always_inline))
__inline__ static void debug_break(void)
{
	trap_instruction();
}
#elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_BULTIN_DEBUGTRAP
__attribute__((always_inline))
__inline__ static void debug_break(void)
{
	__builtin_debugtrap();
}
#elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_BULTIN_TRAP
__attribute__((always_inline))
__inline__ static void debug_break(void)
{
	__builtin_trap();
}
#elif DEBUG_BREAK_IMPL == DEBUG_BREAK_USE_SIGTRAP
#include <signal.h>
__attribute__((always_inline))
__inline__ static void debug_break(void)
{
	raise(SIGTRAP);
}
#else
#error "invalid DEBUG_BREAK_IMPL value"
#endif

#ifdef __cplusplus
}
#endif

#endif /* ifdef _MSC_VER */

#endif /* ifndef DEBUG_BREAK_H */


code:
#ifndef DXTFILTER_H_
#define DXTFILTER_H_

void dxt_handle_io(int32_t len, void *midbuf, char *packbuf);
int32_t dedxt_handle_io(int32_t fil, int32_t, void *midbuf, int32_t mbufsiz, char *packbuf, int32_t ispacked);

int32_t dxtfilter(const texcachepicture *pict, const char *pic, void *midbuf, char *packbuf, uint32_t miplen);
int32_t dedxtfilter(const texcachepicture *pict, char *pic, void *midbuf, char *packbuf, int32_t ispacked);

#endif


code:
#ifndef dynamicgtk_h_
#define dynamicgtk_h_

#include <gdk-pixbuf/gdk-pixdata.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>

#include "compat.h"

#if !GTK_CHECK_VERSION(2,4,0)
#error You need at least 2.4.0 version of GTK+
#endif

#ifndef G_GNUC_NULL_TERMINATED
/* this is a glib-2.8.x thing: */
#define G_GNUC_NULL_TERMINATED
#endif

// glib.h
typedef void (*g_free_ptr) (gpointer mem);

// gobject.h
typedef gpointer (*g_object_get_data_ptr) (GObject *object, const gchar *key);
typedef void (*g_object_set_data_ptr) (GObject *object, const gchar *key, gpointer data);
typedef void (*g_object_set_data_full_ptr) (GObject *object, const gchar *key, gpointer data, GDestroyNotify destroy);
typedef void (*g_object_unref_ptr) (gpointer object);

// gsignal.h
typedef gulong (*g_signal_connect_data_ptr) (gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags);
typedef guint (*g_signal_handlers_block_matched_ptr) (gpointer instance, GSignalMatchType mask, guint signal_id, GQuark detail, GClosure *closure, gpointer func, gpointer data);
typedef guint (*g_signal_handlers_unblock_matched_ptr) (gpointer instance, GSignalMatchType mask, guint signal_id, GQuark detail, GClosure *closure, gpointer func, gpointer data);

// gtype.h
typedef GTypeInstance* (*g_type_check_instance_cast_ptr) (GTypeInstance *instance, GType iface_type);

// gdk-pixdata.h
typedef GdkPixbuf* (*gdk_pixbuf_from_pixdata_ptr) (const GdkPixdata *pixdata, gboolean copy_pixels, GError **error);

// gdk-pixbuf-core.h
typedef GdkPixbuf *(*gdk_pixbuf_new_from_data_ptr) (const guchar *data, GdkColorspace colorspace, gboolean has_alpha, int32_t bits_per_sample, int32_t width, int32_t height, int32_t rowstride, GdkPixbufDestroyNotify destroy_fn, gpointer destroy_fn_data);

// gtkaccelgroup.h
typedef GtkAccelGroup* (*gtk_accel_group_new_ptr) (void);

// gtkalignment.h
typedef GtkWidget* (*gtk_alignment_new_ptr) (gfloat xalign, gfloat yalign, gfloat xscale, gfloat yscale);

// gtkbox.h
typedef GType (*gtk_box_get_type_ptr) (void) G_GNUC_CONST;
typedef void (*gtk_box_pack_start_ptr) (GtkBox *box, GtkWidget *child, gboolean expand, gboolean fill, guint padding);

// gtkbbox.h
typedef GType (*gtk_button_box_get_type_ptr) (void) G_GNUC_CONST;
typedef void (*gtk_button_box_set_layout_ptr) (GtkButtonBox *widget, GtkButtonBoxStyle layout_style);

// gtkbutton.h
typedef GtkWidget* (*gtk_button_new_ptr) (void);

// gtkcelllayout.h
typedef GType (*gtk_cell_layout_get_type_ptr) (void) G_GNUC_CONST;
typedef void (*gtk_cell_layout_pack_start_ptr) (GtkCellLayout *cell_layout, GtkCellRenderer *cell, gboolean expand);
typedef void (*gtk_cell_layout_set_attributes_ptr) (GtkCellLayout *cell_layout, GtkCellRenderer *cell, ...) G_GNUC_NULL_TERMINATED;

// gtkcellrenderertext.h
typedef GtkCellRenderer *(*gtk_cell_renderer_text_new_ptr) (void);

// gtkcheckbutton.h
typedef GtkWidget* (*gtk_check_button_new_with_mnemonic_ptr) (const gchar *label);

// gtkcombobox.h
typedef gint (*gtk_combo_box_get_active_ptr) (GtkComboBox *combo_box);
typedef gboolean (*gtk_combo_box_get_active_iter_ptr) (GtkComboBox *combo_box, GtkTreeIter *iter);
typedef gchar (*gtk_combo_box_get_active_text_ptr) (GtkComboBox *combo_box);
typedef GtkTreeModel *(*gtk_combo_box_get_model_ptr) (GtkComboBox *combo_box);
typedef GType (*gtk_combo_box_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget *(*gtk_combo_box_new_text_ptr) (void);
typedef GtkWidget *(*gtk_combo_box_new_with_model_ptr) (GtkTreeModel *model);
typedef void (*gtk_combo_box_set_active_ptr) (GtkComboBox *combo_box, gint index_);
typedef void (*gtk_combo_box_set_active_iter_ptr) (GtkComboBox *combo_box, GtkTreeIter *iter);

// gtkcontainer.h
typedef void (*gtk_container_add_ptr) (GtkContainer *container, GtkWidget *widget);
typedef void (*gtk_container_foreach_ptr) (GtkContainer *container, GtkCallback callback, gpointer callback_data);
typedef GType (*gtk_container_get_type_ptr) (void) G_GNUC_CONST;
typedef void (*gtk_container_set_border_width_ptr) (GtkContainer *container, guint border_width);

// gtkdialog.h
typedef GType (*gtk_dialog_get_type_ptr) (void) G_GNUC_CONST;
typedef gint (*gtk_dialog_run_ptr) (GtkDialog *dialog);

// gtkfixed.h
// TODO: Only needed to fix compilation for Kenbuild. Bring Kenbuild GTK window to parity with other windows, then remove this again.
typedef GType (*gtk_fixed_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget* (*gtk_fixed_new_ptr) (void);
typedef void (*gtk_fixed_put_ptr) (GtkFixed *fixed, GtkWidget *widget, gint x, gint y);

// gtkhbox.h
typedef GtkWidget* (*gtk_hbox_new_ptr) (gboolean homogeneous, gint spacing);

// gtkhbbox.h
typedef GtkWidget* (*gtk_hbutton_box_new_ptr) (void);

// gtkimage.h
typedef GtkWidget* (*gtk_image_new_from_pixbuf_ptr) (GdkPixbuf *pixbuf);
typedef GtkWidget* (*gtk_image_new_from_stock_ptr) (const gchar *stock_id, GtkIconSize size);

// gtkmain.h
typedef gboolean (*gtk_init_check_ptr) (int32_t *argc, char ***argv);

// gtklabel.h
typedef GType (*gtk_label_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget* (*gtk_label_new_ptr) (const gchar *str);
typedef GtkWidget* (*gtk_label_new_with_mnemonic_ptr) (const gchar *str);
typedef void (*gtk_label_set_mnemonic_widget_ptr) (GtkLabel *label, GtkWidget *widget);

// gtkliststore.h
typedef void (*gtk_list_store_append_ptr) (GtkListStore *list_store, GtkTreeIter *iter);
typedef void (*gtk_list_store_clear_ptr) (GtkListStore *list_store);
typedef GType (*gtk_list_store_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkListStore *(*gtk_list_store_new_ptr) (gint n_columns, ...);
typedef void (*gtk_list_store_set_ptr) (GtkListStore *list_store, GtkTreeIter *iter, ...);

// gtkmain.h
typedef gboolean (*gtk_events_pending_ptr) (void);
typedef void (*gtk_main_ptr) (void);
typedef gboolean (*gtk_main_iteration_do_ptr) (gboolean blocking);
typedef void (*gtk_main_quit_ptr) (void);

// gtkmessagedialog.h
typedef GtkWidget* (*gtk_message_dialog_new_ptr) (GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, const gchar *message_format, ...) G_GNUC_PRINTF (5, 6);

// gtkmisc.h
typedef GType (*gtk_misc_get_type_ptr) (void) G_GNUC_CONST;
typedef void (*gtk_misc_set_alignment_ptr) (GtkMisc *misc, gfloat xalign, gfloat yalign);

// gtknotebook.h
typedef GtkWidget* (*gtk_notebook_get_nth_page_ptr) (GtkNotebook *notebook, gint page_num);
typedef GType (*gtk_notebook_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget * (*gtk_notebook_new_ptr) (void);
typedef void (*gtk_notebook_set_current_page_ptr) (GtkNotebook *notebook, gint page_num);
typedef void (*gtk_notebook_set_tab_label_ptr) (GtkNotebook *notebook, GtkWidget *child, GtkWidget *tab_label);

// gtkobject.h
typedef GtkType (*gtk_object_get_type_ptr) (void) G_GNUC_CONST;

// gtkscrolledwindow.h
typedef GType (*gtk_scrolled_window_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget* (*gtk_scrolled_window_new_ptr) (GtkAdjustment *hadjustment, GtkAdjustment *vadjustment);
typedef void (*gtk_scrolled_window_set_policy_ptr) (GtkScrolledWindow *scrolled_window, GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy);
typedef void (*gtk_scrolled_window_set_shadow_type_ptr) (GtkScrolledWindow *scrolled_window, GtkShadowType type);

// gtktable.h
typedef GType (*gtk_table_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget* (*gtk_table_new_ptr) (guint rows, guint columns, gboolean homogeneous);
typedef void (*gtk_table_attach_ptr) (GtkTable *table, GtkWidget *child, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach, GtkAttachOptions xoptions, GtkAttachOptions yoptions, guint xpadding, guint ypadding);

// gtktextbuffer.h
typedef gboolean (*gtk_text_buffer_backspace_ptr) (GtkTextBuffer *buffer, GtkTextIter *iter, gboolean interactive, gboolean default_editable);
typedef GtkTextMark *(*gtk_text_buffer_create_mark_ptr) (GtkTextBuffer *buffer, const gchar *mark_name, const GtkTextIter *where, gboolean left_gravity);
typedef void (*gtk_text_buffer_delete_mark_ptr) (GtkTextBuffer *buffer, GtkTextMark *mark);
typedef void (*gtk_text_buffer_get_end_iter_ptr) (GtkTextBuffer *buffer, GtkTextIter *iter);
typedef void (*gtk_text_buffer_insert_ptr) (GtkTextBuffer *buffer, GtkTextIter *iter, const gchar *text, gint len);

// gtktextiter.h
// FIXME: should I put a #if !GTK_CHECK_VERSION(2,6,0)
// around these three, or should I not care?
typedef gboolean (*gtk_text_iter_backward_cursor_position_ptr) (GtkTextIter *iter);
typedef gboolean (*gtk_text_iter_equal_ptr) (const GtkTextIter *lhs, const GtkTextIter *rhs);
typedef gboolean (*gtk_text_buffer_delete_interactive_ptr) (GtkTextBuffer *buffer, GtkTextIter *start_iter, GtkTextIter *end_iter, gboolean default_editable);

// gtktextview.h
typedef GtkTextBuffer *(*gtk_text_view_get_buffer_ptr) (GtkTextView *text_view);
typedef GType (*gtk_text_view_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget * (*gtk_text_view_new_ptr) (void);
typedef void (*gtk_text_view_scroll_to_mark_ptr) (GtkTextView *text_view, GtkTextMark *mark, gdouble within_margin, gboolean use_align, gdouble xalign, gdouble yalign);
typedef void (*gtk_text_view_set_cursor_visible_ptr) (GtkTextView *text_view, gboolean setting);
typedef void (*gtk_text_view_set_editable_ptr) (GtkTextView *text_view, gboolean setting);
typedef void (*gtk_text_view_set_left_margin_ptr) (GtkTextView *text_view, gint left_margin);
typedef void (*gtk_text_view_set_right_margin_ptr) (GtkTextView *text_view, gint right_margin);
typedef void (*gtk_text_view_set_wrap_mode_ptr) (GtkTextView *text_view, GtkWrapMode wrap_mode);

// gtktogglebutton.h
typedef gboolean (*gtk_toggle_button_get_active_ptr) (GtkToggleButton *toggle_button);
typedef GType (*gtk_toggle_button_get_type_ptr) (void) G_GNUC_CONST;
typedef void (*gtk_toggle_button_set_active_ptr) (GtkToggleButton *toggle_button, gboolean is_active);

// gtktreemodel.h
typedef void (*gtk_tree_model_get_ptr) (GtkTreeModel *tree_model, GtkTreeIter *iter, ...);
typedef gboolean (*gtk_tree_model_get_iter_ptr) (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path);
typedef GtkTreePath * (*gtk_tree_model_get_path_ptr) (GtkTreeModel *tree_model, GtkTreeIter *iter);
typedef GType (*gtk_tree_model_get_type_ptr) (void) G_GNUC_CONST;
typedef gint *(*gtk_tree_path_get_indices_ptr) (GtkTreePath *path);
typedef GtkTreePath *(*gtk_tree_path_new_from_indices_ptr) (gint first_index, ...);

// gtktreeselection.h
typedef gboolean (*gtk_tree_selection_get_selected_ptr) (GtkTreeSelection *selection, GtkTreeModel **model, GtkTreeIter *iter);
typedef void (*gtk_tree_selection_select_iter_ptr) (GtkTreeSelection *selection, GtkTreeIter *iter);
typedef GType (*gtk_tree_selection_get_type_ptr) (void) G_GNUC_CONST;
typedef void (*gtk_tree_selection_set_mode_ptr) (GtkTreeSelection *selection, GtkSelectionMode type);

// gtktreesortable.h
typedef GType (*gtk_tree_sortable_get_type_ptr) (void) G_GNUC_CONST;
typedef void (*gtk_tree_sortable_set_sort_column_id_ptr) (GtkTreeSortable *sortable, gint sort_column_id, GtkSortType order);
typedef void (*gtk_tree_sortable_set_sort_func_ptr) (GtkTreeSortable *sortable, gint sort_column_id, GtkTreeIterCompareFunc sort_func, gpointer user_data, GtkDestroyNotify destroy);

// gtktreeview.h
typedef GType (*gtk_tree_view_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget *(*gtk_tree_view_new_with_model_ptr) (GtkTreeModel *model);
typedef GtkTreeModel *(*gtk_tree_view_get_model_ptr) (GtkTreeView *tree_view);
typedef GtkTreeSelection *(*gtk_tree_view_get_selection_ptr) (GtkTreeView *tree_view);
typedef gint (*gtk_tree_view_append_column_ptr) (GtkTreeView *tree_view, GtkTreeViewColumn *column);
typedef void (*gtk_tree_view_set_enable_search_ptr) (GtkTreeView *tree_view, gboolean enable_search);
typedef void (*gtk_tree_view_set_headers_visible_ptr) (GtkTreeView *tree_view, gboolean headers_visible);

// gtktreeviewcolumn.h
typedef GtkTreeViewColumn *(*gtk_tree_view_column_new_with_attributes_ptr) (const gchar *title, GtkCellRenderer *cell, ...) G_GNUC_NULL_TERMINATED;
typedef void (*gtk_tree_view_column_set_expand_ptr) (GtkTreeViewColumn *tree_column, gboolean expand);
typedef void (*gtk_tree_view_column_set_min_width_ptr) (GtkTreeViewColumn *tree_column, gint min_width);

// gtkvbox.h
typedef GtkWidget* (*gtk_vbox_new_ptr) (gboolean homogeneous, gint spacing);

// gtkwidget.h
typedef void (*gtk_widget_add_accelerator_ptr) (GtkWidget *widget, const gchar *accel_signal, GtkAccelGroup *accel_group, guint accel_key, GdkModifierType accel_mods, GtkAccelFlags accel_flags);
typedef void (*gtk_widget_destroy_ptr) (GtkWidget *widget);
typedef GtkWidget* (*gtk_widget_ref_ptr) (GtkWidget *widget);
typedef void (*gtk_widget_set_sensitive_ptr) (GtkWidget *widget, gboolean sensitive);
typedef void (*gtk_widget_set_size_request_ptr) (GtkWidget *widget, gint width, gint height);
typedef void (*gtk_widget_show_all_ptr) (GtkWidget *widget);
typedef void (*gtk_widget_show_ptr) (GtkWidget *widget);
typedef void (*gtk_widget_unref_ptr) (GtkWidget *widget);

// gtkwindow.h
typedef void (*gtk_window_add_accel_group_ptr) (GtkWindow *window, GtkAccelGroup *accel_group);
typedef GType (*gtk_window_get_type_ptr) (void) G_GNUC_CONST;
typedef GtkWidget* (*gtk_window_new_ptr) (GtkWindowType type);
typedef void (*gtk_window_set_default_icon_ptr) (GdkPixbuf *icon);
typedef void (*gtk_window_set_position_ptr) (GtkWindow *window, GtkWindowPosition position);
typedef void (*gtk_window_set_resizable_ptr) (GtkWindow *window, gboolean resizable);
typedef void (*gtk_window_set_title_ptr) (GtkWindow *window, const gchar *title);
typedef void (*gtk_window_set_type_hint_ptr) (GtkWindow *window, GdkWindowTypeHint hint);
typedef void (*gtk_window_set_default_ptr) (GtkWindow *window, GtkWidget *default_widget);

// gunicode.h
typedef gint (*g_utf8_collate_ptr) (const gchar *str1, const gchar *str2);

struct _dynamicgtksyms {
    g_free_ptr g_free;
    g_object_get_data_ptr g_object_get_data;
    g_object_set_data_ptr g_object_set_data;
    g_object_set_data_full_ptr g_object_set_data_full;
    g_object_unref_ptr g_object_unref;
    g_signal_connect_data_ptr g_signal_connect_data;
    g_signal_handlers_block_matched_ptr g_signal_handlers_block_matched;
    g_signal_handlers_unblock_matched_ptr g_signal_handlers_unblock_matched;
    g_type_check_instance_cast_ptr g_type_check_instance_cast;
    gdk_pixbuf_from_pixdata_ptr gdk_pixbuf_from_pixdata;
    gdk_pixbuf_new_from_data_ptr gdk_pixbuf_new_from_data;
    gtk_accel_group_new_ptr gtk_accel_group_new;
    gtk_alignment_new_ptr gtk_alignment_new;
    gtk_box_get_type_ptr gtk_box_get_type;
    gtk_box_pack_start_ptr gtk_box_pack_start;
    gtk_button_box_get_type_ptr gtk_button_box_get_type;
    gtk_button_box_set_layout_ptr gtk_button_box_set_layout;
    gtk_button_new_ptr gtk_button_new;
    gtk_cell_layout_get_type_ptr gtk_cell_layout_get_type;
    gtk_cell_layout_pack_start_ptr gtk_cell_layout_pack_start;
    gtk_cell_layout_set_attributes_ptr gtk_cell_layout_set_attributes;
    gtk_cell_renderer_text_new_ptr gtk_cell_renderer_text_new;
    gtk_check_button_new_with_mnemonic_ptr gtk_check_button_new_with_mnemonic;
    gtk_combo_box_get_active_ptr gtk_combo_box_get_active;
    gtk_combo_box_get_active_iter_ptr gtk_combo_box_get_active_iter;
    gtk_combo_box_get_active_text_ptr gtk_combo_box_get_active_text;
    gtk_combo_box_get_model_ptr gtk_combo_box_get_model;
    gtk_combo_box_get_type_ptr gtk_combo_box_get_type;
    gtk_combo_box_new_text_ptr gtk_combo_box_new_text;
    gtk_combo_box_new_with_model_ptr gtk_combo_box_new_with_model;
    gtk_combo_box_set_active_ptr gtk_combo_box_set_active;
    gtk_combo_box_set_active_iter_ptr gtk_combo_box_set_active_iter;
    gtk_container_add_ptr gtk_container_add;
    gtk_container_foreach_ptr gtk_container_foreach;
    gtk_container_get_type_ptr gtk_container_get_type;
    gtk_container_set_border_width_ptr gtk_container_set_border_width;
    gtk_dialog_get_type_ptr gtk_dialog_get_type;
    gtk_dialog_run_ptr gtk_dialog_run;
    gtk_fixed_get_type_ptr gtk_fixed_get_type;
    gtk_fixed_new_ptr gtk_fixed_new;
    gtk_fixed_put_ptr gtk_fixed_put;
    gtk_hbox_new_ptr gtk_hbox_new;
    gtk_hbutton_box_new_ptr gtk_hbutton_box_new;
    gtk_image_new_from_pixbuf_ptr gtk_image_new_from_pixbuf;
    gtk_image_new_from_stock_ptr gtk_image_new_from_stock;
    gtk_init_check_ptr gtk_init_check;
    gtk_label_get_type_ptr gtk_label_get_type;
    gtk_label_new_ptr gtk_label_new;
    gtk_label_new_with_mnemonic_ptr gtk_label_new_with_mnemonic;
    gtk_label_set_mnemonic_widget_ptr gtk_label_set_mnemonic_widget;
    gtk_list_store_append_ptr gtk_list_store_append;
    gtk_list_store_clear_ptr gtk_list_store_clear;
    gtk_list_store_get_type_ptr gtk_list_store_get_type;
    gtk_list_store_new_ptr gtk_list_store_new;
    gtk_list_store_set_ptr gtk_list_store_set;
    gtk_events_pending_ptr gtk_events_pending;
    gtk_main_ptr gtk_main;
    gtk_main_iteration_do_ptr gtk_main_iteration_do;
    gtk_main_quit_ptr gtk_main_quit;
    gtk_message_dialog_new_ptr gtk_message_dialog_new;
    gtk_misc_get_type_ptr gtk_misc_get_type;
    gtk_misc_set_alignment_ptr gtk_misc_set_alignment;
    gtk_notebook_get_nth_page_ptr gtk_notebook_get_nth_page;
    gtk_notebook_get_type_ptr gtk_notebook_get_type;
    gtk_notebook_new_ptr gtk_notebook_new;
    gtk_notebook_set_current_page_ptr gtk_notebook_set_current_page;
    gtk_notebook_set_tab_label_ptr gtk_notebook_set_tab_label;
    gtk_object_get_type_ptr gtk_object_get_type;
    gtk_scrolled_window_get_type_ptr gtk_scrolled_window_get_type;
    gtk_scrolled_window_new_ptr gtk_scrolled_window_new;
    gtk_scrolled_window_set_policy_ptr gtk_scrolled_window_set_policy;
    gtk_scrolled_window_set_shadow_type_ptr gtk_scrolled_window_set_shadow_type;
    gtk_table_get_type_ptr gtk_table_get_type;
    gtk_table_new_ptr gtk_table_new;
    gtk_table_attach_ptr gtk_table_attach;
    gtk_text_buffer_backspace_ptr gtk_text_buffer_backspace;
    gtk_text_buffer_create_mark_ptr gtk_text_buffer_create_mark;
    gtk_text_buffer_delete_mark_ptr gtk_text_buffer_delete_mark;
    gtk_text_buffer_get_end_iter_ptr gtk_text_buffer_get_end_iter;
    gtk_text_buffer_insert_ptr gtk_text_buffer_insert;
    // FIXME: should I put a #if !GTK_CHECK_VERSION(2,6,0)
    // around these three, or should I not care?
    gtk_text_iter_backward_cursor_position_ptr gtk_text_iter_backward_cursor_position;
    gtk_text_iter_equal_ptr gtk_text_iter_equal;
    gtk_text_buffer_delete_interactive_ptr gtk_text_buffer_delete_interactive;
    //
    gtk_text_view_get_buffer_ptr gtk_text_view_get_buffer;
    gtk_text_view_get_type_ptr gtk_text_view_get_type;
    gtk_text_view_new_ptr gtk_text_view_new;
    gtk_text_view_scroll_to_mark_ptr gtk_text_view_scroll_to_mark;
    gtk_text_view_set_cursor_visible_ptr gtk_text_view_set_cursor_visible;
    gtk_text_view_set_editable_ptr gtk_text_view_set_editable;
    gtk_text_view_set_left_margin_ptr gtk_text_view_set_left_margin;
    gtk_text_view_set_right_margin_ptr gtk_text_view_set_right_margin;
    gtk_text_view_set_wrap_mode_ptr gtk_text_view_set_wrap_mode;
    gtk_toggle_button_get_active_ptr gtk_toggle_button_get_active;
    gtk_toggle_button_get_type_ptr gtk_toggle_button_get_type;
    gtk_toggle_button_set_active_ptr gtk_toggle_button_set_active;
    gtk_tree_model_get_ptr gtk_tree_model_get;
    gtk_tree_model_get_iter_ptr gtk_tree_model_get_iter;
    gtk_tree_model_get_path_ptr gtk_tree_model_get_path;
    gtk_tree_model_get_type_ptr gtk_tree_model_get_type;
    gtk_tree_path_get_indices_ptr gtk_tree_path_get_indices;
    gtk_tree_path_new_from_indices_ptr gtk_tree_path_new_from_indices;
    gtk_tree_selection_get_selected_ptr gtk_tree_selection_get_selected;
    gtk_tree_selection_select_iter_ptr gtk_tree_selection_select_iter;
    gtk_tree_selection_set_mode_ptr gtk_tree_selection_set_mode;
    gtk_tree_sortable_get_type_ptr gtk_tree_sortable_get_type;
    gtk_tree_sortable_set_sort_column_id_ptr gtk_tree_sortable_set_sort_column_id;
    gtk_tree_sortable_set_sort_func_ptr gtk_tree_sortable_set_sort_func;
    gtk_tree_view_append_column_ptr gtk_tree_view_append_column;
    gtk_tree_view_column_new_with_attributes_ptr gtk_tree_view_column_new_with_attributes;
    gtk_tree_view_column_set_expand_ptr gtk_tree_view_column_set_expand;
    gtk_tree_view_column_set_min_width_ptr gtk_tree_view_column_set_min_width;
    gtk_tree_view_get_model_ptr gtk_tree_view_get_model;
    gtk_tree_view_get_selection_ptr gtk_tree_view_get_selection;
    gtk_tree_view_get_type_ptr gtk_tree_view_get_type;
    gtk_tree_view_new_with_model_ptr gtk_tree_view_new_with_model;
    gtk_tree_view_set_enable_search_ptr gtk_tree_view_set_enable_search;
    gtk_tree_view_set_headers_visible_ptr gtk_tree_view_set_headers_visible;
    gtk_vbox_new_ptr gtk_vbox_new;
    gtk_widget_add_accelerator_ptr gtk_widget_add_accelerator;
    gtk_widget_destroy_ptr gtk_widget_destroy;
    gtk_widget_ref_ptr gtk_widget_ref;
    gtk_widget_set_sensitive_ptr gtk_widget_set_sensitive;
    gtk_widget_set_size_request_ptr gtk_widget_set_size_request;
    gtk_widget_show_all_ptr gtk_widget_show_all;
    gtk_widget_show_ptr gtk_widget_show;
    gtk_widget_unref_ptr gtk_widget_unref;
    gtk_window_add_accel_group_ptr gtk_window_add_accel_group;
    gtk_window_get_type_ptr gtk_window_get_type;
    gtk_window_new_ptr gtk_window_new;
    gtk_window_set_default_icon_ptr gtk_window_set_default_icon;
    gtk_window_set_position_ptr gtk_window_set_position;
    gtk_window_set_resizable_ptr gtk_window_set_resizable;
    gtk_window_set_title_ptr gtk_window_set_title;
    gtk_window_set_type_hint_ptr gtk_window_set_type_hint;
    gtk_window_set_default_ptr gtk_window_set_default;
    g_utf8_collate_ptr g_utf8_collate;
};
extern struct _dynamicgtksyms dynamicgtksyms;

int32_t dynamicgtk_init(void);
void dynamicgtk_uninit(void);

#ifndef dynamicgtkfoo__

// glib.h
#define g_free dynamicgtksyms.g_free

// gobject.h
#define g_object_get_data dynamicgtksyms.g_object_get_data
#define g_object_set_data dynamicgtksyms.g_object_set_data
#define g_object_set_data_full dynamicgtksyms.g_object_set_data_full
#define g_object_unref dynamicgtksyms.g_object_unref

// gsignal.h
#define g_signal_connect_data dynamicgtksyms.g_signal_connect_data
#define g_signal_handlers_block_matched dynamicgtksyms.g_signal_handlers_block_matched
#define g_signal_handlers_unblock_matched dynamicgtksyms.g_signal_handlers_unblock_matched

// gtype.h
#define g_type_check_instance_cast dynamicgtksyms.g_type_check_instance_cast

// gdk-pixdata.h
#define gdk_pixbuf_from_pixdata dynamicgtksyms.gdk_pixbuf_from_pixdata

// gdk-pixbuf-core.h
#define gdk_pixbuf_new_from_data dynamicgtksyms.gdk_pixbuf_new_from_data

// gtkaccelgroup.h
#define gtk_accel_group_new dynamicgtksyms.gtk_accel_group_new

// gtkalignment.h
#define gtk_alignment_new dynamicgtksyms.gtk_alignment_new

// gtkbox.h
#define gtk_box_get_type dynamicgtksyms.gtk_box_get_type
#define gtk_box_pack_start dynamicgtksyms.gtk_box_pack_start

// gtkbbox.h
#define gtk_button_box_get_type dynamicgtksyms.gtk_button_box_get_type
#define gtk_button_box_set_layout dynamicgtksyms.gtk_button_box_set_layout

// gtkbutton.h
#define gtk_button_new dynamicgtksyms.gtk_button_new

// gtkcelllayout.h
#define gtk_cell_layout_get_type dynamicgtksyms.gtk_cell_layout_get_type
#define gtk_cell_layout_pack_start dynamicgtksyms.gtk_cell_layout_pack_start
#define gtk_cell_layout_set_attributes dynamicgtksyms.gtk_cell_layout_set_attributes

// gtkcellrenderertext.h
#define gtk_cell_renderer_text_new dynamicgtksyms.gtk_cell_renderer_text_new

// gtkcheckbutton.h
#define gtk_check_button_new_with_mnemonic dynamicgtksyms.gtk_check_button_new_with_mnemonic

// gtkcombobox.h
#define gtk_combo_box_get_active dynamicgtksyms.gtk_combo_box_get_active
#define gtk_combo_box_get_active_iter dynamicgtksyms.gtk_combo_box_get_active_iter
#define gtk_combo_box_get_active_text dynamicgtksyms.gtk_combo_box_get_active_text
#define gtk_combo_box_get_model dynamicgtksyms.gtk_combo_box_get_model
#define gtk_combo_box_get_type dynamicgtksyms.gtk_combo_box_get_type
#define gtk_combo_box_new_text dynamicgtksyms.gtk_combo_box_new_text
#define gtk_combo_box_new_with_model dynamicgtksyms.gtk_combo_box_new_with_model
#define gtk_combo_box_set_active dynamicgtksyms.gtk_combo_box_set_active
#define gtk_combo_box_set_active_iter dynamicgtksyms.gtk_combo_box_set_active_iter

// gtkcontainer.h
#define gtk_container_add dynamicgtksyms.gtk_container_add
#define gtk_container_foreach dynamicgtksyms.gtk_container_foreach
#define gtk_container_get_type dynamicgtksyms.gtk_container_get_type
#define gtk_container_set_border_width dynamicgtksyms.gtk_container_set_border_width

// gtkdialog.h
#define gtk_dialog_get_type dynamicgtksyms.gtk_dialog_get_type
#define gtk_dialog_run dynamicgtksyms.gtk_dialog_run

// gtkfixed.h
// TODO: Only needed to fix compilation for Kenbuild. Bring Kenbuild GTK window to parity with other windows, then remove this again.
#define gtk_fixed_get_type dynamicgtksyms.gtk_fixed_get_type
#define gtk_fixed_new dynamicgtksyms.gtk_fixed_new
#define gtk_fixed_put dynamicgtksyms.gtk_fixed_put

// gtkhbox.h
#define gtk_hbox_new dynamicgtksyms.gtk_hbox_new

// gtkhbbox.h
#define gtk_hbutton_box_new dynamicgtksyms.gtk_hbutton_box_new

// gtkimage.h
#define gtk_image_new_from_pixbuf dynamicgtksyms.gtk_image_new_from_pixbuf
#define gtk_image_new_from_stock dynamicgtksyms.gtk_image_new_from_stock

// gtkmain.h
#define gtk_init_check dynamicgtksyms.gtk_init_check

// gtklabel.h
#define gtk_label_get_type dynamicgtksyms.gtk_label_get_type
#define gtk_label_new dynamicgtksyms.gtk_label_new
#define gtk_label_new_with_mnemonic dynamicgtksyms.gtk_label_new_with_mnemonic
#define gtk_label_set_mnemonic_widget dynamicgtksyms.gtk_label_set_mnemonic_widget

// gtkliststore.h
#define gtk_list_store_append dynamicgtksyms.gtk_list_store_append
#define gtk_list_store_clear dynamicgtksyms.gtk_list_store_clear
#define gtk_list_store_get_type dynamicgtksyms.gtk_list_store_get_type
#define gtk_list_store_new dynamicgtksyms.gtk_list_store_new
#define gtk_list_store_set dynamicgtksyms.gtk_list_store_set

// gtkmain.h
#define gtk_events_pending dynamicgtksyms.gtk_events_pending
#define gtk_main dynamicgtksyms.gtk_main
#define gtk_main_iteration_do dynamicgtksyms.gtk_main_iteration_do
#define gtk_main_quit dynamicgtksyms.gtk_main_quit

// gtkmessagedialog.h
#define gtk_message_dialog_new dynamicgtksyms.gtk_message_dialog_new

// gtkmisc.h
#define gtk_misc_get_type dynamicgtksyms.gtk_misc_get_type
#define gtk_misc_set_alignment dynamicgtksyms.gtk_misc_set_alignment

// gtknotebook.h
#define gtk_notebook_get_nth_page dynamicgtksyms.gtk_notebook_get_nth_page
#define gtk_notebook_get_type dynamicgtksyms.gtk_notebook_get_type
#define gtk_notebook_new dynamicgtksyms.gtk_notebook_new
#define gtk_notebook_set_current_page dynamicgtksyms.gtk_notebook_set_current_page
#define gtk_notebook_set_tab_label dynamicgtksyms.gtk_notebook_set_tab_label

// gtkobject.h
#define gtk_object_get_type dynamicgtksyms.gtk_object_get_type

// gtkscrolledwindow.h
#define gtk_scrolled_window_get_type dynamicgtksyms.gtk_scrolled_window_get_type
#define gtk_scrolled_window_new dynamicgtksyms.gtk_scrolled_window_new
#define gtk_scrolled_window_set_policy dynamicgtksyms.gtk_scrolled_window_set_policy
#define gtk_scrolled_window_set_shadow_type dynamicgtksyms.gtk_scrolled_window_set_shadow_type

// gtktable.h
#define gtk_table_get_type dynamicgtksyms.gtk_table_get_type
#define gtk_table_new dynamicgtksyms.gtk_table_new
#define gtk_table_attach dynamicgtksyms.gtk_table_attach

// gtktextbuffer.h
#define gtk_text_buffer_backspace dynamicgtksyms.gtk_text_buffer_backspace
#define gtk_text_buffer_create_mark dynamicgtksyms.gtk_text_buffer_create_mark
#define gtk_text_buffer_delete_mark dynamicgtksyms.gtk_text_buffer_delete_mark
#define gtk_text_buffer_get_end_iter dynamicgtksyms.gtk_text_buffer_get_end_iter
#define gtk_text_buffer_insert dynamicgtksyms.gtk_text_buffer_insert

// gtktextiter.h
#define gtk_text_iter_backward_cursor_position dynamicgtksyms.gtk_text_iter_backward_cursor_position
#define gtk_text_iter_equal dynamicgtksyms.gtk_text_iter_equal
#define gtk_text_buffer_delete_interactive dynamicgtksyms.gtk_text_buffer_delete_interactive

// gtktextview.h
#define gtk_text_view_get_buffer dynamicgtksyms.gtk_text_view_get_buffer
#define gtk_text_view_get_type dynamicgtksyms.gtk_text_view_get_type
#define gtk_text_view_new dynamicgtksyms.gtk_text_view_new
#define gtk_text_view_scroll_to_mark dynamicgtksyms.gtk_text_view_scroll_to_mark
#define gtk_text_view_set_cursor_visible dynamicgtksyms.gtk_text_view_set_cursor_visible
#define gtk_text_view_set_editable dynamicgtksyms.gtk_text_view_set_editable
#define gtk_text_view_set_left_margin dynamicgtksyms.gtk_text_view_set_left_margin
#define gtk_text_view_set_right_margin dynamicgtksyms.gtk_text_view_set_right_margin
#define gtk_text_view_set_wrap_mode dynamicgtksyms.gtk_text_view_set_wrap_mode

// gtktogglebutton.h
#define gtk_toggle_button_get_active dynamicgtksyms.gtk_toggle_button_get_active
#define gtk_toggle_button_get_type dynamicgtksyms.gtk_toggle_button_get_type
#define gtk_toggle_button_set_active dynamicgtksyms.gtk_toggle_button_set_active

// gtktreemodel.h
#define gtk_tree_model_get dynamicgtksyms.gtk_tree_model_get
#define gtk_tree_model_get_iter dynamicgtksyms.gtk_tree_model_get_iter
#define gtk_tree_model_get_path dynamicgtksyms.gtk_tree_model_get_path
#define gtk_tree_model_get_type dynamicgtksyms.gtk_tree_model_get_type
#define gtk_tree_path_get_indices dynamicgtksyms.gtk_tree_path_get_indices
#define gtk_tree_path_new_from_indices dynamicgtksyms.gtk_tree_path_new_from_indices

// gtktreeselection.h
#define gtk_tree_selection_get_selected dynamicgtksyms.gtk_tree_selection_get_selected
#define gtk_tree_selection_select_iter dynamicgtksyms.gtk_tree_selection_select_iter
#define gtk_tree_selection_set_mode dynamicgtksyms.gtk_tree_selection_set_mode

// gtktreesortable.h
#define gtk_tree_sortable_get_type dynamicgtksyms.gtk_tree_sortable_get_type
#define gtk_tree_sortable_set_sort_column_id dynamicgtksyms.gtk_tree_sortable_set_sort_column_id
#define gtk_tree_sortable_set_sort_func dynamicgtksyms.gtk_tree_sortable_set_sort_func

// gtktreeview.h
#define gtk_tree_view_append_column dynamicgtksyms.gtk_tree_view_append_column
#define gtk_tree_view_get_model dynamicgtksyms.gtk_tree_view_get_model
#define gtk_tree_view_get_selection dynamicgtksyms.gtk_tree_view_get_selection
#define gtk_tree_view_get_type dynamicgtksyms.gtk_tree_view_get_type
#define gtk_tree_view_new_with_model dynamicgtksyms.gtk_tree_view_new_with_model
#define gtk_tree_view_set_enable_search dynamicgtksyms.gtk_tree_view_set_enable_search
#define gtk_tree_view_set_headers_visible dynamicgtksyms.gtk_tree_view_set_headers_visible

// gtktreeviewcolumn.h
#define gtk_tree_view_column_new_with_attributes dynamicgtksyms.gtk_tree_view_column_new_with_attributes
#define gtk_tree_view_column_set_expand dynamicgtksyms.gtk_tree_view_column_set_expand
#define gtk_tree_view_column_set_min_width dynamicgtksyms.gtk_tree_view_column_set_min_width

// gtkvbox.h
#define gtk_vbox_new dynamicgtksyms.gtk_vbox_new

// gtkwidget.h
#define gtk_widget_add_accelerator dynamicgtksyms.gtk_widget_add_accelerator
#define gtk_widget_destroy dynamicgtksyms.gtk_widget_destroy
#define gtk_widget_ref dynamicgtksyms.gtk_widget_ref
#define gtk_widget_set_sensitive dynamicgtksyms.gtk_widget_set_sensitive
#define gtk_widget_set_size_request dynamicgtksyms.gtk_widget_set_size_request
#define gtk_widget_show_all dynamicgtksyms.gtk_widget_show_all
#define gtk_widget_show dynamicgtksyms.gtk_widget_show
#define gtk_widget_unref dynamicgtksyms.gtk_widget_unref

// gtkwindow.h
#define gtk_window_add_accel_group dynamicgtksyms.gtk_window_add_accel_group
#define gtk_window_get_type dynamicgtksyms.gtk_window_get_type
#define gtk_window_new dynamicgtksyms.gtk_window_new
#define gtk_window_set_default_icon dynamicgtksyms.gtk_window_set_default_icon
#define gtk_window_set_position dynamicgtksyms.gtk_window_set_position
#define gtk_window_set_resizable dynamicgtksyms.gtk_window_set_resizable
#define gtk_window_set_title dynamicgtksyms.gtk_window_set_title
#define gtk_window_set_type_hint dynamicgtksyms.gtk_window_set_type_hint
#define gtk_window_set_default dynamicgtksyms.gtk_window_set_default

// gunicode.h
#define g_utf8_collate dynamicgtksyms.g_utf8_collate

#endif	/* __dynamicgtkfoo__ */

#endif	/* dynamicgtk_h_ */


code:
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
//
// This file has been modified from Ken Silverman's original release
// by Jonathon Fowler (jf@jonof.id.au)
// by the EDuke32 team (development@voidpoint.com)

#ifndef editor_h_
#define editor_h_

#include "compat.h"
#include "baselayer.h"

#ifdef __cplusplus
extern "C" {
#endif

extern const char *defaultsetupfilename;
extern char setupfilename[BMAX_PATH];

extern char levelname[BMAX_PATH];

// Build keys
#define BK_MOVEFORWARD   0
#define BK_MOVEBACKWARD  1
#define BK_TURNLEFT 	 2
#define BK_TURNRIGHT	 3
#define BK_RUN  		 4
#define BK_STRAFE   	 5
//#define BK_SHOOT		 6
//#define BK_OPEN 		 7
#define BK_MOVEUP   	 8
#define BK_MOVEDOWN 	 9
//#define BK_LOOKUP   	10
//#define BK_LOOKDOWN 	11
//#define BK_STRAFELEFT   12
//#define BK_STRAFERIGHT  13
#define BK_MODE2D_3D	14
//#define BK_PLAYERVIEW   15
//#define BK_ZOOMIN   	16
//#define BK_ZOOMOUT  	17
//#define BK_MESSAGE  	18
#define BK_CONSOLE  	19
#define NUMBUILDKEYS 20

extern int32_t horiz;
extern vec3_t pos;
extern int16_t ang, cursectnum;
extern int32_t g_doHardcodedMovement;

extern int8_t m32_clipping;  // 0: none, 1: only white walls, 2: like game

extern int16_t editstatus, searchit;
extern int32_t searchx, searchy, osearchx, osearchy;      //search input

extern int16_t searchsector, searchwall, searchstat;  //search output
extern int16_t searchbottomwall, searchisbottom;
extern int32_t zmode, kensplayerheight, zlock;

extern int16_t newnumwalls, joinsector[2];
extern int16_t highlightsector[MAXSECTORS], highlightsectorcnt;
extern int16_t highlight[MAXWALLS+MAXSPRITES];
extern int16_t asksave;

extern int16_t pointhighlight, linehighlight, sectorhighlight, highlightcnt;

extern int16_t defaultspritecstat;

extern int32_t tempsectornum;
extern int32_t temppicnum, tempcstat, templotag, temphitag, tempextra;
extern uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning, tempypanning;
extern int32_t tempshade, tempxvel, tempyvel, tempzvel;
extern int32_t tempstatnum, tempblend;
extern char somethingintab;

extern char names[MAXTILES][25];
extern uint8_t buildkeys[NUMBUILDKEYS];

extern float vid_gamma_3d, vid_contrast_3d, vid_brightness_3d;
extern double msens;

extern vec3_t startpos;
extern int16_t startang, startsectnum;

extern int32_t lastpm16time, synctics;
extern int32_t halfxdim16, midydim16, zoom;
extern int32_t ydim16, bppgame, forcesetup;
extern int32_t unrealedlook, quickmapcycling;
extern int32_t pk_turnaccel,pk_turndecel,pk_uedaccel;
extern int32_t revertCTRL,scrollamount;
extern int32_t autosave;
extern int32_t mlook;
extern int16_t prefixtiles[10];

extern int32_t showfirstwall;

extern int32_t graphicsmode;

extern int32_t grid, autogrid;
extern int32_t editorgridextent;	// in engine.c

extern char game_executable[BMAX_PATH];
extern const char* DefaultGameExec;
extern const char* DefaultGameLocalExec;

extern char program_origcwd[BMAX_PATH];
extern const char *mapster32_fullpath;
extern char *testplay_addparam;
extern const char *g_namesFileName;

extern int32_t gridlock;

extern int32_t g_maxCacheSize;

extern int osdvisible;
extern int32_t g_lazy_tileselector;
extern bool m32_osd_tryscript;
extern int32_t showheightindicators;
extern int32_t showambiencesounds;

extern int32_t numgraysects;
extern uint8_t graysectbitmap[(MAXSECTORS+7)>>3];
extern uint8_t graywallbitmap[(MAXWALLS+7)>>3];
extern int32_t autogray, showinnergray;

extern void drawgradient(void);

#ifdef YAX_ENABLE
int32_t yax_is121(int16_t bunchnum, int16_t getfloor);
#endif

extern void M32_DrawRoomsAndMasks(void);

extern void yax_tweakpicnums(int32_t bunchnum, int32_t cf, int32_t restore);  // editor-only
extern void M32_ResetFakeRORTiles(void);

//// Interactive Scaling
struct iscdata_t {
    int8_t active, rotatep;
    vec2_t piv;  // pivot point
    int32_t dragx, dragy;  // dragged point
    int32_t xsc, ysc, ang;
};

extern iscdata_t isc;

#define EDITING_MAP_P() (newnumwalls>=0 || joinsector[0]>=0 || circlewall>=0 || (bstatus&1) || isc.active)

// set to 1 to enable:
#define M32_UNDO 1
extern int32_t map_revision;
extern int32_t map_undoredo(int32_t dir);
extern void map_undoredo_free(void);
extern void create_map_snapshot(void);

enum
{
    UNDO_SECTORS,
    UNDO_WALLS,
    UNDO_SPRITES
};

typedef struct mapundo_
{
    int32_t revision;
    int32_t num[3];  // numsectors, numwalls, numsprites

    // These exist temporarily as sector/wall/sprite data, but are always compressed
    // +4 bytes refcount at the beginning.
    char *lz4Blocks[3];  // sector, wall, sprite
    int   lz4Size[3];

    uintptr_t crc[3];

    struct mapundo_ *next;  // 'redo' loads this
    struct mapundo_ *prev;  // 'undo' loads this
} mapundo_t;
extern mapundo_t *mapstate;

extern void FuncMenu(void);

// editor side view
extern int32_t m32_sideview;
extern int32_t m32_sideelev;
extern int16_t m32_sideang;
extern int32_t m32_sidecos, m32_sidesin;
extern int32_t m32_swcnt;
extern int32_t m32_wallscreenxy[MAXWALLS][2];
extern int16_t m32_wallsprite[MAXWALLS+MAXSPRITES];
extern int8_t sideview_reversehrot;
extern int32_t scalescreeny(int32_t sy);
extern void editorGet2dScreenCoordinates(int32_t *xres, int32_t *yres, int32_t x, int32_t y, int32_t zoome) ATTRIBUTE((nonnull));
//extern void invscreencoords(int32_t *dx, int32_t *dy, int32_t sx, int32_t sy, int32_t zoome);
extern int32_t getinvdisplacement(int32_t *dx, int32_t *dy, int32_t dz) ATTRIBUTE((nonnull));
extern int32_t getscreenvdisp(int32_t bz, int32_t zoome);
extern void editorSetup2dSideView(void);

extern int8_t keeptexturestretch;
extern int16_t pointhighlightdist, linehighlightdist;

extern void fixrepeats(int16_t i);
extern uint32_t getlenbyrep(int32_t len, int32_t repeat);
extern void fixxrepeat(int16_t wallnum, uint32_t lenrepquot);
extern void AlignWallPoint2(int32_t w0);
extern int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs);

extern void SetFirstWall(int32_t sectnum, int32_t wallnum, int32_t alsoynw);
extern int32_t fixspritesectors(void);
extern void clearkeys(void);

extern const char *ExtGetVer(void);
extern int32_t ExtInit(void);
extern int32_t ExtPreInit(int32_t argc,char const * const * argv);
extern int32_t ExtPostStartupWindow(void);
extern void ExtPostInit(void);
extern void ExtUnInit(void);
extern void ExtPreCheckKeys(void);
extern void ExtAnalyzeSprites(int32_t, int32_t, int32_t, int32_t, int32_t);
extern void ExtCheckKeys(void);
extern void ExtPreLoadMap(void);
extern void ExtSetupMapFilename(const char *mapname);
extern void ExtLoadMap(const char *mapname);
extern int32_t ExtPreSaveMap(void);
extern void ExtSaveMap(const char *mapname);
extern const char *ExtGetSectorCaption(int16_t sectnum);
extern const char *ExtGetWallCaption(int16_t wallnum);
extern const char *ExtGetSpriteCaption(int16_t spritenum);
extern void ExtShowSectorData(int16_t sectnum);
extern void ExtShowWallData(int16_t wallnum);
extern void ExtShowSpriteData(int16_t spritenum);
extern void ExtEditSectorData(int16_t sectnum);
extern void ExtEditWallData(int16_t wallnum);
extern void ExtEditSpriteData(int16_t spritenum);
extern const char *ExtGetSectorType(int32_t lotag);

extern void B_SetBoardFileName(const char *fn);
extern int32_t LoadBoard(const char *filename, uint32_t flags);
extern const char *SaveBoard(const char *fn, uint32_t flags);
extern const char *GetSaveBoardFilename(const char *fn);

extern int32_t clockdir(int32_t wallstart);
extern int32_t loopinside(int32_t x, int32_t y, int16_t startwall);

extern void editorFlipHighlightedSectors(int about_x, int doMirror);

enum {
    // NOTE: These must not be changed, see e.g. loopinside().
    CLOCKDIR_CW = 0,  // outer loop
    CLOCKDIR_CCW = 1,  // inner loop
};

// <loopstart> has to be the starting (i.e. least index) wall of a loop!
//
// The returned value will be either
//  - the starting wall of the next loop of this sector,
//  - the first wall of the next sector, or
//  - out of bounds (== MAXWALLS).
// Thus, it MUST be checked for a proper bound!
static inline int32_t get_nextloopstart(int32_t loopstart)
{
    int32_t i = loopstart;

    while (++i)  // sic
        if (wall[i].point2 == loopstart)
            return i + 1;

    return MAXWALLS;
}

#define CORRUPT_SECTOR (1<<17)
#define CORRUPT_WALL (1<<18)
#define CORRUPT_SPRITE (1<<19)
#define CORRUPT_MASK (CORRUPT_SECTOR|CORRUPT_WALL|CORRUPT_SPRITE)
#define MAXCORRUPTTHINGS 64
extern int32_t corruptlevel, numcorruptthings, corruptthings[MAXCORRUPTTHINGS];
extern int32_t autocorruptcheck;
extern int32_t corruptcheck_noalreadyrefd, corruptcheck_heinum;
extern int32_t corruptcheck_game_duke3d;
extern int32_t corrupt_tryfix_alt;
extern int32_t CheckMapCorruption(int32_t printfromlev, uint64_t tryfixing);

extern int32_t fixmaponsave_sprites;
extern int32_t m32_script_expertmode;  // if true, make read-only vars writable

extern void showsectordata(int16_t sectnum, int16_t small);
extern void showwalldata(int16_t wallnum, int16_t small);
extern void showspritedata(int16_t spritenum, int16_t small);

extern void drawsmallabel(const char *text, char col, char backcol, char border, int32_t dax, int32_t day, int32_t daz);

extern int32_t circlewall;
extern int32_t searchlock;

int32_t loadsetup(const char *fn);	// from config.c
int32_t writesetup(const char *fn);	// from config.c

void editinput(void);
void clearmidstatbar16(void);
void fade_editor_screen(int32_t keepcol);

// internal getnumber* helpers:
extern int32_t getnumber_internal1(char ch, int32_t *danumptr, int32_t maxnumber, char sign);
extern int32_t getnumber_autocomplete(const char *namestart, char ch, int32_t *danum, int32_t flags);

// always CRLF for us
#ifdef _WIN32
# define OURNEWL "\n"
#else
# define OURNEWL "\r\n"
#endif

#ifdef YAX_ENABLE
extern const char *yupdownwall[2];
extern const char *YUPDOWNWALL[2];
#endif

int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t));
#define getnumber256(namestart, num, maxnumber, sign) _getnumber256(namestart, num, maxnumber, sign, NULL)
int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t));
#define getnumber16(namestart, num, maxnumber, sign) _getnumber16(namestart, num, maxnumber, sign, NULL)
void printmessage256(int32_t x, int32_t y, const char *name);
void message(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
void silentmessage(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
extern int32_t AskIfSure(const char *text);

extern char getmessage[162], getmessageleng;
extern int32_t getmessagetimeoff;

extern int32_t mouseaction;

const char* getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen, int32_t completion);

// like snprintf, but pads the output buffer with 'fill' at the end
//int32_t snfillprintf(char *outbuf, size_t bufsiz, int32_t fill, const char *fmt, ...);
void _printmessage16(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));

#define printmessage16(fmt, ...) lastpm16time = (int32_t) totalclock, _printmessage16(fmt, ## __VA_ARGS__)

extern char lastpm16buf[156];

int32_t fillsector_maybetrans(int16_t sectnum, int32_t fillcolor, uint8_t dotrans);  // fillcolor == -1: default (pulsating)
int32_t ask_if_sure(const char *query, uint32_t flags);
int32_t editor_ask_function(const char *question, const char *dachars, int32_t numchars);

static inline int32_t fillsector(int16_t sectnum, int32_t fillcolor)
{
    return fillsector_maybetrans(sectnum, fillcolor, 1);
}

static inline int32_t fillsector_notrans(int16_t sectnum, int32_t fillcolor)
{
    return fillsector_maybetrans(sectnum, fillcolor, 0);
}

void spriteoncfz(int32_t i, int32_t *czptr, int32_t *fzptr) ATTRIBUTE((nonnull(2,3)));
void DoSpriteOrnament(int32_t i);

void getpoint(int32_t searchxe, int32_t searchye, int32_t *x, int32_t *y);
int32_t getpointhighlight(int32_t xplc, int32_t yplc, int32_t point);
void update_highlight(void);
void update_highlightsector(void);
void reset_highlightsector(void);
void reset_highlight(void);
void handlesecthighlight1(int32_t i, int32_t sub, int32_t nograycheck);
void ovh_whiteoutgrab(int32_t restoreredwalls);

int32_t inside_editor_curpos(int16_t sectnum);
void correct_sprite_yoffset(int32_t i);

void inflineintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
                      int32_t x3, int32_t y3, int32_t x4, int32_t y4,
                      int32_t *intx, int32_t *inty, int32_t *sign12, int32_t *sign34);

void ovhscrcoords(int32_t x, int32_t y, int32_t *scrx, int32_t *scry);

extern uint8_t hlsectorbitmap[(MAXSECTORS+7)>>3];

void test_map(int32_t mode);

extern void M32RunScript(const char *s);

////////// tag labeling system //////////
// max (strlen+1), i.e. array length to allocate for a tag label:
#define TAGLAB_MAX 40

extern int32_t taglab_load(const char *filename, int32_t flags);
extern int32_t taglab_save(const char *mapname);

extern void taglab_init();
extern int32_t taglab_add(const char *label, int16_t tag);
extern const char *taglab_getlabel(int16_t tag);
extern int32_t taglab_gettag(const char *label);

extern int32_t taglab_linktags(int32_t spritep, int32_t num);
extern int32_t taglab_getnextfreetag(int32_t *duetoptr);

extern int32_t showtags;

int32_t select_sprite_tag(int32_t spritenum);

extern int32_t m32_2d3dmode, m32_2d3dsize;
extern vec2_t m32_2d3d;
extern int32_t m32_3dundo;

extern int g_useCwd;

#define XSIZE_2D3D (xdim / m32_2d3dsize)
#define YSIZE_2D3D (ydim / m32_2d3dsize)

static inline int32_t m32_is2d3dmode(void)
{
    return !in3dmode() && m32_2d3dmode && (unsigned)cursectnum < MAXSECTORS &&
        searchx > m32_2d3d.x && searchx < (m32_2d3d.x + XSIZE_2D3D) &&
        searchy > m32_2d3d.y && searchy < (m32_2d3d.y + YSIZE_2D3D);
}

extern int32_t editorGet2dSpriteColor(int32_t spr);

extern void editorMaybeLockMouse(int lock);

#define SPRITESEC(j) (sector[sprite[j].sectnum])

#define SCRIPTHISTSIZ 32  // should be the same as OSD_HISTORYDEPTH for maximum win, should be a power of two
extern char *scripthist[SCRIPTHISTSIZ];
extern int32_t scripthistend;

//////////////////// Aiming ////////////////////
#define SEARCH_WALL 0
#define SEARCH_CEILING 1
#define SEARCH_FLOOR 2
#define SEARCH_SPRITE 3
#define SEARCH_MASKWALL 4

#define ASSERT_AIMING ((unsigned)searchstat<=4)

#define AIMING_AT_WALL (searchstat==0)
#define AIMING_AT_CEILING (searchstat==1)
#define AIMING_AT_FLOOR (searchstat==2)
#define AIMING_AT_SPRITE (searchstat==3)
#define AIMING_AT_MASKWALL (searchstat==4)

#define AIMING_AT_WALL_OR_MASK (AIMING_AT_WALL || AIMING_AT_MASKWALL)
#define AIMING_AT_CEILING_OR_FLOOR (AIMING_AT_CEILING || AIMING_AT_FLOOR)

// SaveBoard flags.
enum SaveBoardFlags
{
    M32_SB_NOEXT = 1,  // no ExtSaveMap (backup.map) and no taglabels saving
    M32_SB_ASKOV = 2,  // for NEW_MAP_FORMAT build, ask whether write map if going from V7/8 to VX
};

// showdebug is now used as a general informational on-screen display
#define M32_SHOWDEBUG

// this should be only used if there's no dependency on endwall after the loop.
// of course, users of this macro should know that it modifies startwall and endwall.
#define WALLS_OF_SECTOR(Sect, Itervar) \
    startwall=sector[(Sect)].wallptr, endwall=startwall+sector[(Sect)].wallnum, Itervar=startwall; \
    Itervar < endwall; \
    Itervar++

#define SET_PROTECT_BITS(Var, Newval, Bitstoprotect) do {  \
    (Var) &= (Bitstoprotect);  \
    (Var) |= (Newval) & ~(Bitstoprotect); } while (0)

#define BTAG_MAX 65535
#define BZ_MAX 8388608
#define BHEINUM_MAX 32767

#define M32_MAXPALOOKUPS (MAXPALOOKUPS-RESERVEDPALS-1)

static FORCE_INLINE void inpclamp(int32_t *x, int32_t mi, int32_t ma)
{
    if (*x > ma) *x = ma;
    if (*x < mi) *x = mi;
}

#define drawtranspixel(p, col) drawpixel(p, blendtable[0][(readpixel(p) * 256) + col])

// Timed offset for Mapster32 color index cycling.
// Range: 0 .. 16
#define M32_THROB klabs(sintable[(((int32_t) totalclock << 4) & 2047)] >> 10)
static FORCE_INLINE int throbbinwilliams(int first, int second)
{
    int8_t const dif = second - first;
    return first + ((M32_THROB >> (3 - (klabs(dif) >> 3))) ^ ksgn(dif));
}
static FORCE_INLINE int batmanandthrobbin(void) { return throbbinwilliams(whitecol, editorcolors[0]); }
static FORCE_INLINE int throbandbig(void) { return throbbinwilliams(editorcolors[0], whitecol); }
void m32_showmouse(void);
void editorMaybeWarpMouse(int searchx, int searchy);
#ifdef __cplusplus
}
#endif

#endif