openclonk/standard/inc/Standard.h

409 lines
13 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, 2007 Matthes Bender
* Copyright (c) 2002, 2004-2005, 2007 Sven Eberhardt
* Copyright (c) 2005, 2007, 2009 Peter Wortmann
* Copyright (c) 2005-2009 Günther Brammer
* Copyright (c) 2009 Nicolas Hake
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
/* All kinds of valuable helpers */
#ifndef INC_STANDARD
#define INC_STANDARD
#ifdef HAVE_CONFIG_H
#include <config.h>
#elif defined(_WIN32)
#define HAVE_IO_H 1
#define HAVE_DIRECT_H 1
#define HAVE_SHARE_H 1
#define HAVE_FREETYPE
#endif //_WIN32, HAVE_CONFIG_H
#ifdef _MSC_VER
#pragma warning(disable : 4786) // long symbol names
#pragma warning(disable : 4996) // POSIX name usage
#endif
// debug memory management
#ifndef NODEBUGMEM
#if defined(_DEBUG) && defined(_MSC_VER)
#if _MSC_VER <= 1200
#include <new>
#include <memory>
#include <crtdbg.h>
#include <malloc.h>
inline void *operator new(unsigned int s, const char *szFile, long iLine)
{ return ::operator new(s, _NORMAL_BLOCK, szFile, iLine); }
inline void operator delete(void *p, const char *, long)
{ ::operator delete(p); }
#define new new(__FILE__, __LINE__)
#define malloc(size) ::_malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__)
#else
#include <crtdbg.h>
#endif
#endif
#endif
// Integer dataypes
#ifdef HAVE_STDINT_H
#include <stdint.h>
#elif defined(_MSC_VER)
#include <stddef.h>
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef signed __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef signed int ssize_t;
// Copied from newer stddef.h
#ifndef _INTPTR_T_DEFINED
#ifdef _WIN64
typedef __int64 intptr_t;
#else
typedef __int32 intptr_t;
#endif
#define _INTPTR_T_DEFINED
#endif
#else
#error Could not find integer datatypes!
#endif
#if defined(__GNUC__)
// Allow checks for correct printf-usage
#define GNUC_FORMAT_ATTRIBUTE __attribute__ ((format (printf, 1, 2)))
#define GNUC_FORMAT_ATTRIBUTE_O __attribute__ ((format (printf, 2, 3)))
#define GNUC_ALWAYS_INLINE inline __attribute__ ((always_inline))
#else
#define GNUC_FORMAT_ATTRIBUTE
#define GNUC_FORMAT_ATTRIBUTE_O
#define GNUC_ALWAYS_INLINE inline
#endif
// Temporary-To-Reference-Fix
#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 3))
#define ALLOW_TEMP_TO_REF(ClassName) operator ClassName & () { return *this; }
#else
#define ALLOW_TEMP_TO_REF(ClassName)
#endif
#ifdef HAVE_RVALUE_REF
# define RREF &&
#else
# define RREF &
#endif
#if defined(_DEBUG) && defined(_MSC_VER)
// use inline assembler to invoke the "breakpoint exception"
# define BREAKPOINT_HERE _asm int 3
#elif defined(_DEBUG) && defined(__GNUC__)
# define BREAKPOINT_HERE asm volatile("int $3")
#elif defined(_DEBUG) && defined(HAVE_SIGNAL_H)
# include <signal.h>
# if defined(SIGTRAP)
# define BREAKPOINT_HERE raise(SIGTRAP);
# else
# define BREAKPOINT_HERE
# endif
#else
# define BREAKPOINT_HERE
#endif
#include <string.h>
#ifdef _WIN32
#ifndef _INC_WINDOWS
#define _WIN32_WINDOWS 0x0500
#define _WIN32_WINNT 0x0501
#define WINVER 0x0500
//#define _WIN32_WINNT 0x0500
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#endif
#else // _WIN32
// Boolean datatype
typedef int BOOL;
#define TRUE true
#define FALSE false
// Windows integer types
typedef uint32_t DWORD;
typedef uint8_t BYTE;
typedef uint16_t WORD;
typedef uint32_t UINT;
typedef struct {
long left; long top; long right; long bottom;
} RECT;
#define INFINITE 0xFFFFFFFF
unsigned long timeGetTime(void);
inline int stricmp(const char *s1, const char *s2) {
return strcasecmp(s1, s2);
}
#define GetRValue(rgb) ((unsigned char)(rgb))
#define GetGValue(rgb) ((unsigned char)(((unsigned short)(rgb)) >> 8))
#define GetBValue(rgb) ((unsigned char)((rgb)>>16))
#define RGB(r,g,b) ((DWORD)((BYTE)(r)|((BYTE)(g) << 8)|((BYTE)(b) << 16)))
#define ZeroMemory(d,l) memset((d), 0, (l))
#endif //_WIN32
// These functions have to be provided by the application.
bool Log(const char *szMessage);
bool LogSilent(const char *szMessage);
BOOL LogF(const char *strMessage, ...) GNUC_FORMAT_ATTRIBUTE;
BOOL LogSilentF(const char *strMessage, ...) GNUC_FORMAT_ATTRIBUTE;
#include <memory.h>
#include <math.h>
// Color triplets
#define C4RGB(r, g, b) ((((DWORD)(r)&0xff)<<16)|(((DWORD)(g)&0xff)<<8)|((b)&0xff))
// Small helpers
template <class T> inline T Max(T val1, T val2) { return val1 > val2 ? val1 : val2; }
template <class T> inline T Min(T val1, T val2) { return val1 < val2 ? val1 : val2; }
template <class T> inline T Abs(T val) { return val > 0 ? val : -val; }
template <class T> inline bool Inside(T ival, T lbound, T rbound) { return ival >= lbound && ival <= rbound; }
template <class T> inline T BoundBy(T bval, T lbound, T rbound) { return bval < lbound ? lbound : bval > rbound ? rbound : bval; }
template <class T> inline int Sign(T val) { return val < 0 ? -1 : val > 0 ? 1 : 0; }
template <class T> inline void Swap(T &v1, T &v2) { T t = v1; v1 = v2; v2 = t; }
template <class T> inline void Toggle(T &v) { v = !v; }
const double pi = 3.14159265358979323846;
inline void DWordAlign(int &val)
{
if (val%4) { val>>=2; val<<=2; val+=4; }
}
inline int DWordAligned(int val)
{
if (val%4) { val>>=2; val<<=2; val+=4; }
return val;
}
inline int QWordAligned(int val)
{
if (val%8) { val>>=3; val<<=3; val+=8; }
return val;
}
inline int32_t ForceLimits(int32_t &rVal, int32_t iLow, int32_t iHi)
{
if (rVal<iLow) { rVal=iLow; return -1; }
if (rVal>iHi) { rVal=iHi; return +1; }
return 0;
}
int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2);
int Angle(int iX1, int iY1, int iX2, int iY2);
int Pow(int base, int exponent);
inline void FillMem(void *lpMem, size_t dwSize, char bValue)
{
memset(lpMem,bValue,dwSize);
}
inline void ZeroMem(void *lpMem, size_t dwSize)
{
FillMem(lpMem,dwSize,0);
}
inline bool MemEqual(const void *lpMem1, const void *lpMem2, size_t dwSize)
{
return !memcmp(lpMem1,lpMem2,dwSize);
}
inline void MemCopy(const void *lpMem1, void *lpMem2, size_t dwSize)
{
memmove(lpMem2,lpMem1,dwSize);
}
bool ForLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
bool (*fnCallback)(int32_t, int32_t, int32_t), int32_t iPar=0,
int32_t *lastx=NULL, int32_t *lasty=NULL);
bool PathMove(int &rX, int &rY, int iTargetX, int iTargetY, int iSteps, int &rDelta);
char CharCapital(char cChar);
bool IsIdentifier(char cChar);
bool IsUpperCase(char cChar);
bool IsLowerCase(char cChar);
bool IsWhiteSpace(char cChar);
int SLen(const char *sptr);
int SLenUntil(const char *szStr, char cUntil);
bool SEqual(const char *szStr1, const char *szStr2);
bool SEqual2(const char *szStr1, const char *szStr2);
bool SEqualUntil(const char *szStr1, const char *szStr2, char cWild);
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen=-1);
bool SEqual2NoCase(const char *szStr1, const char *szStr2, int iLen = -1);
int SCompare(const char *szStr1, const char *szStr2);
void SCopy(const char *szSource, char *sTarget, int iMaxL=-1);
void SCopyUntil(const char *szSource, char *sTarget, char cUntil, int iMaxL=-1, int iIndex=0);
void SCopyUntil(const char *szSource, char *sTarget, const char * sUntil, size_t iMaxL);
void SCopyIdentifier(const char *szSource, char *sTarget, int iMaxL=0);
bool SCopyPrecedingIdentifier(const char *pBegin, const char *pIdentifier, char *sTarget, int iSize);
bool SCopySegment(const char *fstr, int segn, char *tstr, char sepa=';', int iMaxL=-1, bool fSkipWhitespace=false);
bool SCopySegmentEx(const char *fstr, int segn, char *tstr, char sepa1, char sepa2, int iMaxL=-1, bool fSkipWhitespace=false);
bool SCopyNamedSegment(const char *szString, const char *szName, char *sTarget, char cSeparator=';', char cNameSeparator='=', int iMaxL=-1);
bool SCopyEnclosed(const char *szSource, char cOpen, char cClose, char *sTarget, int iSize);
void SAppend(const char *szSource, char *szTarget, int iMaxL=-1);
void SAppendChar(char cChar, char *szStr);
void SInsert(char *szString, const char *szInsert, int iPosition=0, int iMaxLen=-1);
void SDelete(char *szString, int iLen, int iPosition=0);
int SCharPos(char cTarget, const char *szInStr, int iIndex=0);
int SCharLastPos(char cTarget, const char *szInStr);
int SCharCount(char cTarget, const char *szInStr, const char *cpUntil=NULL);
int SCharCountEx(const char *szString, const char *szCharList);
void SReplaceChar(char *str, char fc, char tc);
const char *SSearch(const char *szString, const char *szIndex);
const char *SSearchNoCase(const char *szString, const char *szIndex);
const char *SSearchIdentifier(const char *szString, const char *szIndex);
const char *SSearchFunction(const char *szString, const char *szIndex);
const char *SAdvanceSpace(const char *szSPos);
const char *SAdvancePast(const char *szSPos, char cPast);
bool SGetModule(const char *szList, int iIndex, char *sTarget, int iSize=-1);
bool SIsModule(const char *szList, const char *szString, int *ipIndex=NULL, bool fCaseSensitive=false);
bool SAddModule(char *szList, const char *szModule, bool fCaseSensitive=false);
bool SAddModules(char *szList, const char *szModules, bool fCaseSensitive=false);
bool SRemoveModule(char *szList, const char *szModule, bool fCaseSensitive=false);
bool SRemoveModules(char *szList, const char *szModules, bool fCaseSensitive=false);
int SModuleCount(const char *szList);
const char* SGetParameter(const char *strCommandLine, int iParameter, char *strTarget = NULL, int iSize = -1, bool *pWasQuoted = NULL);
void SRemoveComments(char *szScript);
void SNewSegment(char *szStr, const char *szSepa=";");
void SCapitalize(char *szString);
void SWordWrap(char *szText, char cSpace, char cSepa, int iMaxLine);
int SClearFrontBack(char *szString, char cClear=' ');
int SGetLine(const char *szText, const char *cpPosition);
int SLineGetCharacters(const char *szText, const char *cpPosition);
// case sensitive wildcard match with some extra functionality
// can match strings like "*Cl?nk*vour" to "Clonk Endeavour"
BOOL SWildcardMatchEx(const char *szString, const char *szWildcard);
#define LineFeed "\x00D\x00A"
#define EndOfFile "\x020"
#ifdef _WIN32
#define DirSep "\\"
#else
#define DirSep "/"
#endif
void BufferBlit(uint8_t *bypSource, int iSourcePitch,
int iSrcBufHgt, // Positive: Bottom up
int iSrcX, int iSrcY, int iSrcWdt, int iSrcHgt,
uint8_t *bypTarget, int iTargetPitch,
int iTrgBufHgt, // Positive: Bottom up
int iTrgX, int iTrgY, int iTrgWdt, int iTrgHgt);
void BufferBlitDw(uint32_t *bypSource, int iSourcePitch,
int iSrcBufHgt, // Positive: Bottom up
int iSrcX, int iSrcY, int iSrcWdt, int iSrcHgt,
uint32_t *bypTarget, int iTargetPitch,
int iTrgBufHgt, // Positive: Bottom up
int iTrgX, int iTrgY, int iTrgWdt, int iTrgHgt);
void BufferBlitAspect(uint8_t *bypSource, int iSourcePitch,
int iSrcBufHgt, // Positive: Bottom up
int iSrcX, int iSrcY, int iSrcWdt, int iSrcHgt,
uint8_t *bypTarget, int iTargetPitch,
int iTrgBufHgt, // Positive: Bottom up
int iTrgX, int iTrgY, int iTrgWdt, int iTrgHgt);
void BufferBlitAspectDw(uint32_t *bypSource, int iSourcePitch,
int iSrcBufHgt, // Positive: Bottom up
int iSrcX, int iSrcY, int iSrcWdt, int iSrcHgt,
uint32_t *bypTarget, int iTargetPitch,
int iTrgBufHgt, // Positive: Bottom up
int iTrgX, int iTrgY, int iTrgWdt, int iTrgHgt);
void StdBlit(uint8_t *bypSource, int iSourcePitch, int iSrcBufHgt,
int iSrcX, int iSrcY, int iSrcWdt, int iSrcHgt,
uint8_t *bypTarget, int iTargetPitch, int iTrgBufHgt,
int iTrgX, int iTrgY, int iTrgWdt, int iTrgHgt,
int iBytesPerPixel=1, bool fFlip=false);
// sprintf wrapper
#include <stdio.h>
#include <stdarg.h>
#ifdef _MSC_VER
#define vsnprintf _vsnprintf
#endif
// old, insecure sprintf
inline int osprintf(char *str, const char *fmt, ...) GNUC_FORMAT_ATTRIBUTE_O;
inline int osprintf(char *str, const char *fmt, ...)
{
va_list args; va_start(args, fmt);
return vsprintf(str, fmt, args);
}
// wrapper to detect "char *"
template <typename T> struct NoPointer { static void noPointer() { } };
template <> struct NoPointer<char *> { };
// secure sprintf
#define sprintf ssprintf
template <typename T>
inline int ssprintf(T &str, const char *fmt, ...) GNUC_FORMAT_ATTRIBUTE_O;
template <typename T>
inline int ssprintf(T &str, const char *fmt, ...)
{
NoPointer<T>::noPointer();
int n = sizeof(str);
va_list args; va_start(args, fmt);
int m = vsnprintf(str, n, fmt, args);
if(m >= n) { m = n-1; str[m] = 0; }
return m;
}
// open a weblink in an external browser
bool OpenURL(const char *szURL);
#endif // INC_STANDARD