2006-04-13 20:47:06 +00:00
// 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__
2008-11-05 11:49:13 +00:00
# ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# endif
2008-03-22 10:23:57 +00:00
# ifndef UNREFERENCED_PARAMETER
2008-03-26 09:28:21 +00:00
# define UNREFERENCED_PARAMETER(x) x=x
2008-03-22 10:23:57 +00:00
# endif
2010-12-20 16:55:37 +00:00
# if defined __GNUC__ || defined __clang__
# define ATTRIBUTE(attrlist) __attribute__(attrlist)
# else
# define ATTRIBUTE(attrlist)
# endif
2012-12-29 15:21:16 +00:00
# if !defined __clang__ && !defined USING_LTO
# define ATTRIBUTE_OPTIMIZE(str) ATTRIBUTE((optimize(str)))
# else
# define ATTRIBUTE_OPTIMIZE(str)
# endif
2012-11-15 14:28:47 +00:00
# ifndef min
# define min(x,y) ((x) < (y) ? (x) : (y))
# endif
# ifndef max
# define max(x,y) ((x) > (y) ? (x) : (y))
# endif
2008-02-16 22:27:08 +00:00
// This gives us access to 'intptr_t' and 'uintptr_t', which are
// abstractions to the size of a pointer on a given platform
// (ie, they're guaranteed to be the same size as a pointer)
2012-11-05 02:49:08 +00:00
2013-10-07 10:03:11 +00:00
# undef __USE_MINGW_ANSI_STDIO // Workaround for MinGW-w64.
2012-11-05 02:49:08 +00:00
# define __STDC_FORMAT_MACROS
# define __STDC_LIMIT_MACROS
2008-02-16 22:27:08 +00:00
# ifdef HAVE_INTTYPES
2012-11-05 02:49:08 +00:00
# include <stdint.h>
2008-02-16 22:27:08 +00:00
# include <inttypes.h>
2013-02-18 08:50:08 +00:00
// Ghetto. Blame devkitPPC's faulty headers.
# ifdef GEKKO
# undef PRIdPTR
# define PRIdPTR "d"
# undef PRIxPTR
# define PRIxPTR "x"
# undef SCNx32
# define SCNx32 "x"
# endif
2008-06-11 02:33:23 +00:00
# elif defined(_MSC_VER)
# include "msvc / inttypes.h" // from http://code.google.com/p/msinttypes/
2008-02-16 22:27:08 +00:00
# endif
2009-06-18 05:57:10 +00:00
# ifndef _MSC_VER
Win64 support! (Meaning it works, not that we recommend it for everyday use.)
This includes a complete Windows header and library refresh, including the addition of 64-bit compiled libs:
*libogg 1.3.0
*libvorbis 1.3.3
*zlib 1.2.7
*libpng 1.5.13
*libvpx 9a3de881c0e681ba1a79a166a86308bbc84b4acd
*SDL_mixer 1.2.12 (for RENDERTYPE=SDL)
*DirectX import libraries: dsound and dxguid (now included)
To build in 64-bit, you essentially need MinGW's MSYS (but not MinGW itself) and MinGW-w64 at the top of your PATH. The target is automatically detected using `$(CC) -dumpmachine`. The EDukeWiki will get detailed instrucitons.
All compiler and linker warnings when building in 64-bit mode have been fixed.
Remaining 64-bit to-do:
- The ebacktrace dll does not build under 64-bit. It uses code specific to the format of 32-bit executables and will have to be ported to work with 64-bit executables. A future 64-bit version will be named ebacktrace1-64.dll.
- RENDERTYPE=SDL crashes in SDL_mixer's Mix_Linked_Version().
- DirectInput gives an error and does not function. This only affects joysticks, and the error never happens without any plugged in.
- Port the classic renderer ASM to 64-bit. (Just kidding, this is way out of my league.)
This commit includes a fair bit of Makefile development spanning all platforms, including simplifying the SDLCONFIG code, fixing build on Mac OS X (thanks rhoenie!), globally factoring Apple brew/port inclusion, enforcing that all -L come before all -l, and ensuring that $(shell ) is always :='d.
In addition, I have resurrected the old GCC_MAJOR and GCC_MINOR detection using `$(CC) -dumpversion`, but I have made it failsafe in case the command fails or the version is manually specified. I have applied this new fine-grained detection where applicable, including allowing LTO, and restraining -W's to versions that support them.
git-svn-id: https://svn.eduke32.com/eduke32@3278 1a8010ca-5511-0410-912e-c29ae57300e0
2012-12-13 02:37:20 +00:00
# ifndef __fastcall
# if defined(__GNUC__) && defined(__i386__)
2012-09-02 14:13:06 +00:00
# define __fastcall __attribute__((fastcall))
Win64 support! (Meaning it works, not that we recommend it for everyday use.)
This includes a complete Windows header and library refresh, including the addition of 64-bit compiled libs:
*libogg 1.3.0
*libvorbis 1.3.3
*zlib 1.2.7
*libpng 1.5.13
*libvpx 9a3de881c0e681ba1a79a166a86308bbc84b4acd
*SDL_mixer 1.2.12 (for RENDERTYPE=SDL)
*DirectX import libraries: dsound and dxguid (now included)
To build in 64-bit, you essentially need MinGW's MSYS (but not MinGW itself) and MinGW-w64 at the top of your PATH. The target is automatically detected using `$(CC) -dumpmachine`. The EDukeWiki will get detailed instrucitons.
All compiler and linker warnings when building in 64-bit mode have been fixed.
Remaining 64-bit to-do:
- The ebacktrace dll does not build under 64-bit. It uses code specific to the format of 32-bit executables and will have to be ported to work with 64-bit executables. A future 64-bit version will be named ebacktrace1-64.dll.
- RENDERTYPE=SDL crashes in SDL_mixer's Mix_Linked_Version().
- DirectInput gives an error and does not function. This only affects joysticks, and the error never happens without any plugged in.
- Port the classic renderer ASM to 64-bit. (Just kidding, this is way out of my league.)
This commit includes a fair bit of Makefile development spanning all platforms, including simplifying the SDLCONFIG code, fixing build on Mac OS X (thanks rhoenie!), globally factoring Apple brew/port inclusion, enforcing that all -L come before all -l, and ensuring that $(shell ) is always :='d.
In addition, I have resurrected the old GCC_MAJOR and GCC_MINOR detection using `$(CC) -dumpversion`, but I have made it failsafe in case the command fails or the version is manually specified. I have applied this new fine-grained detection where applicable, including allowing LTO, and restraining -W's to versions that support them.
git-svn-id: https://svn.eduke32.com/eduke32@3278 1a8010ca-5511-0410-912e-c29ae57300e0
2012-12-13 02:37:20 +00:00
# else
# define __fastcall
2012-09-02 14:13:06 +00:00
# endif
# endif
2009-06-18 05:57:10 +00:00
# endif
2009-04-26 05:57:42 +00:00
# ifndef TRUE
2012-09-02 14:13:06 +00:00
# define TRUE 1
2009-04-26 05:57:42 +00:00
# endif
# ifndef FALSE
2012-09-02 14:13:06 +00:00
# define FALSE 0
2009-04-26 05:57:42 +00:00
# endif
2010-01-21 10:02:04 +00:00
# define WITHKPLIB
2006-04-13 20:47:06 +00:00
// Define this to rewrite all 'B' versions to library functions. This
// is for platforms which give us a standard sort of C library so we
// link directly. Platforms like PalmOS which don't have a standard C
// library will need to wrap these functions with suitable emulations.
# define __compat_h_macrodef__
2012-11-05 02:49:08 +00:00
# ifdef EXTERNC
2006-08-31 01:54:23 +00:00
# include <cstdarg>
# ifdef __compat_h_macrodef__
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <ctime>
# endif
2006-04-13 20:47:06 +00:00
# else
# include <stdarg.h>
2010-06-23 04:20:46 +00:00
# include <stddef.h>
2006-04-13 20:47:06 +00:00
# endif
# ifdef __compat_h_macrodef__
2012-11-05 02:49:08 +00:00
# ifndef EXTERNC
2006-04-13 20:47:06 +00:00
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <time.h>
# endif
# include <fcntl.h>
# include <ctype.h>
# include <sys / types.h>
# include <sys / stat.h>
# include <errno.h>
# if defined(_WIN32)
# include <io.h>
# else
# include <unistd.h>
# endif
# endif
2012-03-14 22:31:19 +00:00
# include <assert.h>
2006-04-13 20:47:06 +00:00
# ifdef EFENCE
# include <efence.h>
2012-01-12 20:49:34 +00:00
# elif defined DMALLOC
# include <dmalloc.h>
2006-04-13 20:47:06 +00:00
# endif
2009-07-09 02:29:48 +00:00
# if defined(_MSC_VER)
2012-11-15 14:27:57 +00:00
# include <direct.h>
2013-06-27 23:05:24 +00:00
2006-04-13 20:47:06 +00:00
# define longlong(x) x##i64
2013-06-27 23:04:11 +00:00
# if _MSC_VER < 1800
2013-06-27 23:05:24 +00:00
# define inline __inline
2014-02-10 10:59:42 +00:00
# ifndef _WIN64
2010-09-01 02:35:36 +00:00
static inline float nearbyintf ( float x )
{
uint32_t w1 , w2 ;
__asm fnstcw w1
w2 = w1 | 0x00000020 ;
__asm
{
fldcw w2
fld x
frndint
fclex
fldcw w1
}
}
2014-02-10 10:59:42 +00:00
# else
# include <math.h>
static inline float nearbyintf ( float x )
{
if ( x > = 0.0 )
return floorf ( x + 0.5 ) ;
else
return floorf ( x - 0.5 ) ;
}
# endif
2013-06-27 23:04:11 +00:00
# endif
2006-04-13 20:47:06 +00:00
# else
# define longlong(x) x##ll
# endif
2013-07-20 03:36:54 +00:00
# if defined __OPENDINGUX__
//ugly hack
# define nearbyintf rintf
# endif
2006-04-13 20:47:06 +00:00
# ifndef NULL
# define NULL ((void *)0)
# endif
Inreased debugging level for catching oob accesses to 'main' arrays.
If enabled, this makes the following arrays be allocated statically:
spriteext, spritesmooth, sector, wall, sprite, tsprite, while
necessarily disabling the clipshape feature (because it relies on
setting sector/wall to different malloc'd block temporarily).
To compile, pass DEBUGANYWAY=1 in addition to RELEASE=0 to 'make',
and it's really only useful with CC=clang, of course.
git-svn-id: https://svn.eduke32.com/eduke32@2270 1a8010ca-5511-0410-912e-c29ae57300e0
2012-01-19 23:17:34 +00:00
# if DEBUGGINGAIDS>=2
# define DEBUG_MAIN_ARRAYS
# endif
2012-11-05 02:49:08 +00:00
# ifndef DISABLE_INLINING
# define EXTERN_INLINE static inline
# define EXTERN_INLINE_HEADER static inline
# else
2014-01-12 14:04:02 +00:00
# define EXTERN_INLINE __fastcall
# define EXTERN_INLINE_HEADER extern __fastcall
2012-11-05 02:49:08 +00:00
# endif
2012-03-18 08:50:41 +00:00
# if !defined DEBUG_MAIN_ARRAYS
# define HAVE_CLIPSHAPE_FEATURE
# endif
2011-07-20 23:04:20 +00:00
// redefined for apple/ppc, which chokes on stderr when linking...
# define ERRprintf(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
2006-04-13 20:47:06 +00:00
# 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
# define B_ENDIAN_C_INLINE 1
2012-08-19 04:01:04 +00:00
# elif defined(GEKKO) || defined(__ANDROID__)
2012-05-01 12:40:53 +00:00
# define B_LITTLE_ENDIAN 0
# define B_BIG_ENDIAN 1
# define B_ENDIAN_C_INLINE 1
2012-08-19 04:01:04 +00:00
# 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
# define B_SWAP64(x) __swap64(x)
# define B_SWAP32(x) __swap32(x)
# define B_SWAP16(x) __swap16(x)
# elif defined(__FreeBSD__) || defined(__NetBSD__)
2006-04-13 20:47:06 +00:00
# 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
# define B_SWAP64(x) __bswap64(x)
# define B_SWAP32(x) __bswap32(x)
# define B_SWAP16(x) __bswap16(x)
# elif defined(__APPLE__)
2011-07-20 23:04:20 +00:00
# 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
2011-06-17 11:53:41 +00:00
// This hack patches all occurences.
2011-06-17 13:11:19 +00:00
# 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_); })
2011-07-20 23:04:20 +00:00
# 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); })
# undef ERRprintf
# define ERRprintf(fmt, ...) printf(fmt, ## __VA_ARGS__)
# endif
2011-06-17 11:53:41 +00:00
# endif
2006-04-13 20:47:06 +00:00
# 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>
# define B_SWAP64(x) OSSwapConstInt64(x)
# define B_SWAP32(x) OSSwapConstInt32(x)
# define B_SWAP16(x) OSSwapConstInt16(x)
# 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
# define B_ENDIAN_C_INLINE 1
# 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
# define B_ENDIAN_C_INLINE 1
# 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
# define B_ENDIAN_C_INLINE 1
# elif defined(_WIN32) || defined(SKYOS) || defined(__SYLLABLE__)
# define B_LITTLE_ENDIAN 1
# define B_BIG_ENDIAN 0
# define B_ENDIAN_C_INLINE 1
# endif
# if !defined(B_LITTLE_ENDIAN) || !defined(B_BIG_ENDIAN)
# error Unknown endianness
# endif
2014-01-27 10:31:39 +00:00
# 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
2012-11-05 02:49:08 +00:00
# ifdef EXTERNC
2006-08-31 01:54:23 +00:00
# ifndef SCREWED_UP_CPP
2008-11-11 13:24:05 +00:00
// using namespace std;
2006-08-31 01:54:23 +00:00
# endif
2006-04-13 20:47:06 +00:00
extern " C " {
# endif
# if defined B_ENDIAN_X86_INLINE
# if defined(_MSC_VER)
// inline asm using bswap/xchg
# elif defined(__GNUC__)
// inline asm using bswap/xchg
# endif
# elif defined B_ENDIAN_C_INLINE
2009-01-09 09:29:17 +00:00
static inline uint16_t B_SWAP16 ( uint16_t s ) { return ( s > > 8 ) | ( s < < 8 ) ; }
2014-02-10 11:00:25 +00:00
static inline uint32_t B_SWAP32 ( uint32_t l ) { return ( ( l > > 8 ) & 0xff00 ) | ( ( l & 0xff00 ) < < 8 ) | ( l < < 24 ) | ( l > > 24 ) ; }
2009-09-09 07:19:14 +00:00
static inline uint64_t B_SWAP64 ( uint64_t l ) { return ( l > > 56 ) | ( ( l > > 40 ) & 0xff00 ) | ( ( l > > 24 ) & 0xff0000 ) | ( ( l > > 8 ) & 0xff000000 ) | ( ( l & 255 ) < < 56 ) | ( ( l & 0xff00 ) < < 40 ) | ( ( l & 0xff0000 ) < < 24 ) | ( ( l & 0xff000000 ) < < 8 ) ; }
2006-04-13 20:47:06 +00:00
# endif
2014-02-10 11:00:25 +00:00
static inline void B_BUF16 ( uint8_t * buf , uint16_t x )
{
buf [ 0 ] = ( x & 0x00FF ) ;
buf [ 1 ] = ( x & 0xFF00 ) > > 8 ;
}
static inline void B_BUF32 ( uint8_t * buf , uint32_t x )
{
buf [ 0 ] = ( x & 0x000000FF ) ;
buf [ 1 ] = ( x & 0x0000FF00 ) > > 8 ;
buf [ 2 ] = ( x & 0x00FF0000 ) > > 16 ;
buf [ 3 ] = ( x & 0xFF000000 ) > > 24 ;
}
static inline void B_BUF64 ( uint8_t * buf , uint64_t x )
{
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 ;
}
static inline uint16_t B_UNBUF16 ( const uint8_t * buf ) { return ( buf [ 1 ] < < 8 ) | ( buf [ 0 ] ) ; }
static inline uint32_t B_UNBUF32 ( const uint8_t * buf ) { return ( buf [ 3 ] < < 24 ) | ( buf [ 2 ] < < 16 ) | ( buf [ 1 ] < < 8 ) | ( buf [ 0 ] ) ; }
static inline uint64_t B_UNBUF64 ( const uint8_t * buf ) { 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 ] ) ; }
2009-07-09 02:29:48 +00:00
# if defined(USE_MSC_PRAGMAS)
static inline void ftol ( float f , int32_t * a )
{
_asm
{
mov eax , a
fld f
fistp dword ptr [ eax ]
}
}
static inline void dtol ( double d , int32_t * a )
{
_asm
{
mov eax , a
fld d
fistp dword ptr [ eax ]
}
}
# elif defined(USE_GCC_PRAGMAS)
static inline void ftol ( float f , int32_t * a )
{
__asm__ __volatile__ (
#if 0 //(__GNUC__ >= 3)
" flds %1; fistpl %0; "
# else
" flds %1; fistpl (%0); "
# endif
: " =r " ( a ) : " m " ( f ) : " memory " , " cc " ) ;
}
static inline void dtol ( double d , int32_t * a )
{
__asm__ __volatile__ (
#if 0 //(__GNUC__ >= 3)
" fldl %1; fistpl %0; "
# else
" fldl %1; fistpl (%0); "
# endif
: " =r " ( a ) : " m " ( d ) : " memory " , " cc " ) ;
}
# else
static inline void ftol ( float f , int32_t * a )
{
* a = ( int32_t ) f ;
}
static inline void dtol ( double d , int32_t * a )
{
* a = ( int32_t ) d ;
}
# endif
2006-04-13 20:47:06 +00:00
# if B_LITTLE_ENDIAN == 1
# define B_LITTLE64(x) (x)
# define B_BIG64(x) B_SWAP64(x)
# define B_LITTLE32(x) (x)
# define B_BIG32(x) B_SWAP32(x)
# define B_LITTLE16(x) (x)
# define B_BIG16(x) B_SWAP16(x)
# elif B_BIG_ENDIAN == 1
# define B_LITTLE64(x) B_SWAP64(x)
# define B_BIG64(x) (x)
# define B_LITTLE32(x) B_SWAP32(x)
# define B_BIG32(x) (x)
# define B_LITTLE16(x) B_SWAP16(x)
# define B_BIG16(x) (x)
# endif
# ifndef FP_OFF
2008-04-25 11:21:08 +00:00
# define FP_OFF(__p) ((uintptr_t)(__p))
2006-04-13 20:47:06 +00:00
# endif
# ifdef __compat_h_macrodef__
# ifndef O_BINARY
# define O_BINARY 0
# endif
# ifndef O_TEXT
# define O_TEXT 0
# endif
# ifndef F_OK
# define F_OK 0
# endif
# 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
2012-08-19 04:01:04 +00:00
# ifdef __ANDROID__
# define BS_IWRITE S_IWUSR
# define BS_IREAD S_IRUSR
# else
# define BS_IWRITE S_IWRITE
# define BS_IREAD S_IREAD
# endif
2006-04-13 20:47:06 +00:00
# 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
# else
# define BO_BINARY 0
# define BO_TEXT 1
# define BO_RDONLY 2
# define BO_WRONLY 4
# define BO_RDWR 6
# define BO_APPEND 8
# define BO_CREAT 16
# define BO_TRUNC 32
# define BS_IRGRP 0
# define BS_IWGRP 0
# define BS_IEXEC 1
# define BS_IWRITE 2
# define BS_IREAD 4
# define BS_IFIFO 0x1000
# define BS_IFCHR 0x2000
# define BS_IFBLK 0x3000
# define BS_IFDIR 0x4000
# define BS_IFREG 0x8000
# define BSEEK_SET 0
# define BSEEK_CUR 1
# define BSEEK_END 2
# endif
# ifdef UNDERSCORES
# define ASMSYM(x) "_" x
# else
# define ASMSYM(x) x
# endif
# ifndef min
# define min(a,b) ( ((a) < (b)) ? (a) : (b) )
# endif
# ifndef max
# define max(a,b) ( ((a) > (b)) ? (a) : (b) )
# endif
2011-03-23 17:41:01 +00:00
# if __GNUC__ >= 4
2013-05-16 21:54:59 +00:00
# define CLAMP_DECL static inline __attribute__((warn_unused_result))
2011-03-23 17:41:01 +00:00
# else
2013-05-16 21:54:59 +00:00
# define CLAMP_DECL static inline
2011-03-23 17:41:01 +00:00
# endif
2013-05-16 21:54:59 +00:00
// Clamp <in> to [<min>..<max>]. The case in <= min is handled first.
CLAMP_DECL int32_t clamp ( int32_t in , int32_t min , int32_t max )
2011-03-19 18:07:12 +00:00
{
2012-03-04 20:14:18 +00:00
return in < = min ? min : ( in > = max ? max : in ) ;
2011-03-19 18:07:12 +00:00
}
2006-04-13 20:47:06 +00:00
2013-05-16 21:54:59 +00:00
// Clamp <in> to [<min>..<max>]. The case in >= max is handled first.
CLAMP_DECL int32_t clamp2 ( int32_t in , int32_t min , int32_t max )
{
return in > = max ? max : ( in < = min ? min : in ) ;
}
2014-04-12 08:45:08 +00:00
// Clamp <in> to [<min>..<max>]. The case in <= min is handled first.
CLAMP_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.
CLAMP_DECL float fclamp2 ( float in , float min , float max )
{
return in > = max ? max : ( in < = min ? min : in ) ;
}
2009-07-12 01:55:34 +00:00
# define BMAX_PATH 256
2006-04-13 20:47:06 +00:00
struct Bdirent {
2009-01-09 09:29:17 +00:00
uint16_t namlen ;
2006-04-13 20:47:06 +00:00
char * name ;
2009-04-26 05:57:42 +00:00
uint32_t mode ;
uint32_t size ;
uint32_t mtime ;
2006-04-13 20:47:06 +00:00
} ;
typedef void BDIR ;
BDIR * Bopendir ( const char * name ) ;
struct Bdirent * Breaddir ( BDIR * dir ) ;
2009-01-09 09:29:17 +00:00
int32_t Bclosedir ( BDIR * dir ) ;
2006-04-13 20:47:06 +00:00
2013-01-20 01:00:00 +00:00
# ifdef _MSC_VER
typedef intptr_t ssize_t ;
# endif
2006-04-13 20:47:06 +00:00
# ifdef __compat_h_macrodef__
2006-08-31 01:54:23 +00:00
typedef FILE BFILE ;
2006-04-13 20:47:06 +00:00
# define bsize_t size_t
# define bssize_t ssize_t
# else
2006-08-31 01:54:23 +00:00
typedef void BFILE ;
2009-01-09 09:29:17 +00:00
typedef uint32_t bsize_t ;
2009-04-26 05:57:42 +00:00
typedef int32_t bssize_t ;
2006-04-13 20:47:06 +00:00
# endif
2011-11-05 12:13:50 +00:00
# if RAND_MAX == 32767
static 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 inline uint16_t system_15bit_rand ( void ) { return ( ( uint16_t ) rand ( ) ) & 0x7fff ; }
# endif
2006-04-13 20:47:06 +00:00
2012-03-01 23:36:11 +00:00
# if defined(_MSC_VER)
// XXX: non-__compat_h_macrodef__ version?
# define strtoll _strtoi64
# endif
2006-04-13 20:47:06 +00:00
# ifdef __compat_h_macrodef__
2012-03-26 22:04:24 +00:00
# define Bassert assert
2006-04-13 20:47:06 +00:00
# define Brand rand
# define Balloca alloca
2011-11-10 21:47:42 +00:00
# define Bmalloc malloc
# define Bcalloc calloc
# define Brealloc realloc
2011-11-05 12:13:50 +00:00
# define Bfree free
# define Bstrdup strdup
# define Bmemalign memalign
2006-04-13 20:47:06 +00:00
# define Bopen open
# define Bclose close
# define Bwrite write
# define Bread read
# define Blseek lseek
# if defined(__GNUC__)
# define Btell(h) lseek(h,0,SEEK_CUR)
# else
# define Btell tell
# endif
2012-11-15 14:27:57 +00:00
# ifdef _MSC_VER
2006-04-13 20:47:06 +00:00
# define Bstat stat
2012-11-15 14:27:57 +00:00
# define Bfstat fstat
# else
# define Bstat stat
# define Bfstat fstat
# endif
2012-11-15 06:42:37 +00:00
# define Bfileno fileno
# define Bferror ferror
2006-04-13 20:47:06 +00:00
# define Bfopen fopen
# define Bfclose fclose
2012-06-03 16:08:27 +00:00
# define Bfflush fflush
2006-04-13 20:47:06 +00:00
# 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
2012-03-18 08:48:32 +00:00
# define Bfscanf fscanf
# define Bfseek fseek
2012-03-23 20:23:46 +00:00
# define Bftell ftell
# define Bputs puts
2006-04-13 20:47:06 +00:00
# define Bstrcpy strcpy
# define Bstrncpy strncpy
# define Bstrcmp strcmp
# define Bstrncmp strncmp
2009-07-09 02:29:48 +00:00
# if defined(_MSC_VER)
# define Bstrcasecmp _stricmp
# define Bstrncasecmp _strnicmp
# else
# if defined(__QNX__)
2006-04-13 20:47:06 +00:00
# define Bstrcasecmp stricmp
# define Bstrncasecmp strnicmp
# else
# define Bstrcasecmp strcasecmp
# define Bstrncasecmp strncasecmp
# endif
2009-07-09 02:29:48 +00:00
# endif
2006-04-13 20:47:06 +00:00
# if defined(_WIN32)
# define Bstrlwr strlwr
# define Bstrupr strupr
# define Bmkdir(s,x) mkdir(s)
# else
# define Bmkdir mkdir
# endif
# define Bstrcat strcat
# define Bstrncat strncat
# define Bstrlen strlen
# define Bstrchr strchr
# define Bstrrchr strrchr
2012-03-04 20:14:18 +00:00
// 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))
2012-02-20 21:17:39 +00:00
# define Batoi(str) ((int32_t)strtol(str, NULL, 10))
# define Batol(str) (strtol(str, NULL, 10))
2012-03-23 20:23:46 +00:00
# define Batof(str) (strtod(str, NULL))
2006-04-13 20:47:06 +00:00
# define Bstrtol strtol
# define Bstrtoul strtoul
# define Bstrtod strtod
2011-01-16 02:51:22 +00:00
# define Bstrstr strstr
2013-06-01 06:55:00 +00:00
# define Bislower islower
# define Bisupper isupper
# define Bisdigit isdigit
2006-04-13 20:47:06 +00:00
# define Btoupper toupper
# define Btolower tolower
# define Bmemcpy memcpy
# define Bmemmove memmove
# define Bmemchr memchr
# define Bmemset memset
# define Bmemcmp memcmp
2012-03-23 20:23:46 +00:00
# define Bscanf scanf
2006-04-13 20:47:06 +00:00
# define Bprintf printf
2012-03-23 20:23:46 +00:00
# define Bsscanf sscanf
2006-04-13 20:47:06 +00:00
# define Bsprintf sprintf
# ifdef _MSC_VER
# define Bsnprintf _snprintf
# define Bvsnprintf _vsnprintf
# else
# define Bsnprintf snprintf
# define Bvsnprintf vsnprintf
# endif
# define Bvfprintf vfprintf
# define Bgetcwd getcwd
# define Bgetenv getenv
# define Btime() time(NULL)
2012-12-14 23:10:10 +00:00
# define Butime utime
2006-04-13 20:47:06 +00:00
# else
2012-03-26 22:04:24 +00:00
void Bassert ( int ) ;
2009-01-09 09:29:17 +00:00
int32_t Brand ( void ) ;
2006-04-13 20:47:06 +00:00
void * Bmalloc ( bsize_t size ) ;
void Bfree ( void * ptr ) ;
2009-01-09 09:29:17 +00:00
int32_t Bopen ( const char * pathname , int32_t flags , unsigned mode ) ;
int32_t Bclose ( int32_t fd ) ;
bssize_t Bwrite ( int32_t fd , const void * buf , bsize_t count ) ;
bssize_t Bread ( int32_t fd , void * buf , bsize_t count ) ;
int32_t Blseek ( int32_t fildes , int32_t offset , int32_t whence ) ;
2006-04-13 20:47:06 +00:00
BFILE * Bfopen ( const char * path , const char * mode ) ;
2009-01-09 09:29:17 +00:00
int32_t Bfclose ( BFILE * stream ) ;
int32_t Bfeof ( BFILE * stream ) ;
int32_t Bfgetc ( BFILE * stream ) ;
2006-04-13 20:47:06 +00:00
void Brewind ( BFILE * stream ) ;
2009-01-09 09:29:17 +00:00
char * Bfgets ( char * s , int32_t size , BFILE * stream ) ;
int32_t Bfputc ( int32_t c , BFILE * stream ) ;
int32_t Bfputs ( const char * s , BFILE * stream ) ;
2006-04-13 20:47:06 +00:00
bsize_t Bfread ( void * ptr , bsize_t size , bsize_t nmemb , BFILE * stream ) ;
bsize_t Bfwrite ( const void * ptr , bsize_t size , bsize_t nmemb , BFILE * stream ) ;
char * Bstrdup ( const char * s ) ;
char * Bstrcpy ( char * dest , const char * src ) ;
char * Bstrncpy ( char * dest , const char * src , bsize_t n ) ;
2009-01-09 09:29:17 +00:00
int32_t Bstrcmp ( const char * s1 , const char * s2 ) ;
int32_t Bstrncmp ( const char * s1 , const char * s2 , bsize_t n ) ;
int32_t Bstrcasecmp ( const char * s1 , const char * s2 ) ;
int32_t Bstrncasecmp ( const char * s1 , const char * s2 , bsize_t n ) ;
2006-04-13 20:47:06 +00:00
char * Bstrcat ( char * dest , const char * src ) ;
char * Bstrncat ( char * dest , const char * src , bsize_t n ) ;
bsize_t Bstrlen ( const char * s ) ;
2009-01-09 09:29:17 +00:00
char * Bstrchr ( const char * s , int32_t c ) ;
char * Bstrrchr ( const char * s , int32_t c ) ;
int32_t Batoi ( const char * nptr ) ;
int32_t Batol ( const char * nptr ) ;
2010-12-20 16:55:37 +00:00
int32_t Bstrtol ( const char * nptr , char * * endptr , int32_t base ) ;
uint32_t Bstrtoul ( const char * nptr , char * * endptr , int32_t base ) ;
2006-04-13 20:47:06 +00:00
void * Bmemcpy ( void * dest , const void * src , bsize_t n ) ;
void * Bmemmove ( void * dest , const void * src , bsize_t n ) ;
2009-01-09 09:29:17 +00:00
void * Bmemchr ( const void * s , int32_t c , bsize_t n ) ;
void * Bmemset ( void * s , int32_t c , bsize_t n ) ;
int32_t Bmemcmp ( const void * s1 , const void * s2 , bsize_t n ) ;
2010-12-20 16:55:37 +00:00
int32_t Bprintf ( const char * format , . . . ) ATTRIBUTE ( ( format ( printf , 1 , 2 ) ) ) ;
int32_t Bsprintf ( char * str , const char * format , . . . ) ATTRIBUTE ( ( format ( printf , 2 , 3 ) ) ) ;
int32_t Bsnprintf ( char * str , bsize_t size , const char * format , . . . ) ATTRIBUTE ( ( format ( printf , 3 , 4 ) ) ) ;
2009-01-09 09:29:17 +00:00
int32_t Bvsnprintf ( char * str , bsize_t size , const char * format , va_list ap ) ;
2006-04-13 20:47:06 +00:00
char * Bgetcwd ( char * buf , bsize_t size ) ;
char * Bgetenv ( const char * name ) ;
# endif
char * Bgethomedir ( void ) ;
2009-01-09 09:29:17 +00:00
char * Bgetsupportdir ( int32_t global ) ;
uint32_t Bgetsysmemsize ( void ) ;
int32_t Bcorrectfilename ( char * filename , int32_t removefn ) ;
int32_t Bcanonicalisefilename ( char * filename , int32_t removefn ) ;
2006-04-13 20:47:06 +00:00
char * Bgetsystemdrives ( void ) ;
2009-01-09 09:29:17 +00:00
int32_t Bfilelength ( int32_t fd ) ;
2011-02-21 23:08:21 +00:00
char * Bstrtoken ( char * s , const char * delim , char * * ptrptr , int32_t chop ) ;
2012-03-12 04:48:42 +00:00
char * Bstrtolower ( char * str ) ;
2009-01-09 09:29:17 +00:00
int32_t Bwildmatch ( const char * i , const char * j ) ;
2006-04-13 20:47:06 +00:00
# if !defined(_WIN32)
char * Bstrlwr ( char * ) ;
char * Bstrupr ( char * ) ;
# endif
2013-05-06 19:43:38 +00:00
// Copy min(strlen(src)+1, n) characters into dst, always terminate with a NUL.
2012-11-20 01:33:22 +00:00
static inline char * Bstrncpyz ( char * dst , const char * src , bsize_t n )
{
Bstrncpy ( dst , src , n ) ;
dst [ n - 1 ] = 0 ;
return dst ;
}
2013-05-06 19:43:38 +00:00
// Append extension when <outbuf> contains no dot.
2013-06-13 17:10:56 +00:00
// <ext> can be like ".mhk" or like "_crash.map", no need to start with a dot.
2013-05-06 19:43:38 +00:00
// 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
2013-06-13 17:10:56 +00:00
Bstrcpy ( p , ext ) ;
2013-05-06 19:43:38 +00:00
}
2014-05-30 00:02:16 +00:00
# ifdef DEBUGGINGAIDS
extern void xalloc_set_location ( int32_t line , const char * file , const char * func ) ;
# endif
void set_memerr_handler ( void ( * handlerfunc ) ( int32_t , const char * , const char * ) ) ;
char * xstrdup ( const char * s ) ;
void * xmalloc ( bsize_t size ) ;
void * xcalloc ( bsize_t nmemb , bsize_t size ) ;
void * xrealloc ( void * ptr , bsize_t size ) ;
2012-11-05 02:49:08 +00:00
# ifdef EXTERNC
2006-04-13 20:47:06 +00:00
}
# endif
2014-04-17 19:58:31 +00:00
# define DO_FREE_AND_NULL(var) do { \
if ( var ! = NULL ) { Bfree ( var ) ; var = NULL ; } \
} while ( 0 )
2012-09-05 17:25:31 +00:00
# define MAYBE_FCLOSE_AND_NULL(fileptr) do { \
if ( fileptr ) { Bfclose ( fileptr ) ; fileptr = NULL ; } \
} while ( 0 )
2012-11-25 13:54:33 +00:00
# define NOWARN(print_func, fmt, ...) do { \
2012-11-15 14:28:04 +00:00
print_func ( fmt , # # __VA_ARGS__ ) ; \
} while ( 0 )
2012-11-25 13:54:33 +00:00
# define NOWARN_RETURN(print_func, var, fmt, ...) do { \
2012-11-15 14:28:04 +00:00
var = print_func ( fmt , # # __VA_ARGS__ ) ; \
} while ( 0 )
2012-11-25 13:54:33 +00:00
# ifdef __cplusplus
2012-11-26 08:25:26 +00:00
# ifndef FORCE_WARNINGS
2012-11-25 13:54:33 +00:00
# ifdef _MSC_VER
2012-11-25 13:19:12 +00:00
// TODO: add MSVC pragmas to disable equivalent warning, if necessary later
2012-11-25 13:54:33 +00:00
# else
# ifdef _WIN32
2012-11-25 13:19:12 +00:00
// MinGW's _Pragma is completely broken so our GCC NOWARN macro is useless there
2012-11-25 13:54:33 +00:00
# pragma GCC diagnostic ignored "-Wformat"
# else
# undef NOWARN
# undef NOWARN_RETURN
# define NOWARN(print_func, fmt, ...) do { _Pragma("GCC diagnostic ignored \"-Wformat\"") \
2012-11-15 14:28:04 +00:00
print_func ( fmt , # # __VA_ARGS__ ) ; \
_Pragma ( " GCC diagnostic warning \" -Wformat \" " ) } while ( 0 )
2012-11-25 13:54:33 +00:00
# define NOWARN_RETURN(print_func, var, fmt, ...) do { _Pragma("GCC diagnostic ignored \"-Wformat\"") \
2012-11-15 14:28:04 +00:00
var = print_func ( fmt , # # __VA_ARGS__ ) ; \
_Pragma ( " GCC diagnostic warning \" -Wformat \" " ) } while ( 0 )
2012-11-25 13:54:33 +00:00
# endif // _WIN32
# endif // _MSC_VER
2012-11-26 08:25:26 +00:00
# endif // FORCE_WARNINGS
2012-11-15 23:35:40 +00:00
# endif // __cplusplus
2012-11-15 14:28:04 +00:00
# define OSD_Printf_nowarn(fmt, ...) NOWARN(OSD_Printf, fmt, ## __VA_ARGS__)
# define Bsprintf_nowarn(fmt, ...) NOWARN(Bsprintf, fmt, ## __VA_ARGS__)
# define Bsprintf_nowarn_return(x, fmt, ...) NOWARN_RETURN(Bsprintf, x, fmt, ## __VA_ARGS__)
# define initprintf_nowarn(fmt, ...) NOWARN(initprintf, fmt, ## __VA_ARGS__)
# define message_nowarn(fmt, ...) NOWARN(message, fmt, ## __VA_ARGS__)
2013-04-05 17:53:14 +00:00
/* 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)
# ifdef __COUNTER__
# define EDUKE32_STATIC_ASSERT(cond) \
extern void EDUKE32_ASSERT_NAME ( __COUNTER__ ) ( int STATIC_ASSERTION_FAILED [ ( cond ) ? 1 : - 1 ] )
# else
# define EDUKE32_STATIC_ASSERT(cond) \
extern void EDUKE32_ASSERT_NAME ( __LINE__ ) ( int STATIC_ASSERTION_FAILED [ ( cond ) ? 1 : - 1 ] )
# endif
2013-12-12 19:22:16 +00:00
# define ARRAY_SIZE(Ar) (sizeof(Ar) / sizeof((Ar)[0]))
# define ARRAY_SSIZE(Ar) (bssize_t)ARRAY_SIZE(Ar)
2014-05-30 00:02:16 +00:00
////////// PANICKING ALLOCATION MACROS (wrapping the functions) //////////
# ifdef DEBUGGINGAIDS
// Detection of __func__ or equivalent functionality, found in SDL_assert.h
# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */
# define EDUKE32_FUNCTION __func__
# elif ((__GNUC__ >= 2) || defined(_MSC_VER))
# define EDUKE32_FUNCTION __FUNCTION__
# else
# define EDUKE32_FUNCTION "???"
# endif
# define EDUKE32_PRE_XALLLOC xalloc_set_location(__LINE__, __FILE__, EDUKE32_FUNCTION)
# define Xstrdup(s) (EDUKE32_PRE_XALLLOC, xstrdup(s))
# define Xmalloc(size) (EDUKE32_PRE_XALLLOC, xmalloc(size))
# define Xcalloc(nmemb, size) (EDUKE32_PRE_XALLLOC, xcalloc(nmemb, size))
# define Xrealloc(ptr, size) (EDUKE32_PRE_XALLLOC, xrealloc(ptr, size))
# else
# define Xstrdup xstrdup
# define Xmalloc xmalloc
# define Xcalloc xcalloc
# define Xrealloc xrealloc
# endif
//////////
2006-04-13 20:47:06 +00:00
# endif // __compat_h__
2012-11-25 13:54:33 +00:00