text: //
  // Abstracted type/compiler definitions for portability
  // 
  
  #pragma once
  
  //
  // Subset of MSVC warnings promoted to errors so compile will fail even if /WX isn't used
  //  
  
  #ifdef _WINDOWS_
  
  #pragma warning (error:4265)        // Class has virtual functions but destructor is not virtual
  #pragma warning (error:4035)        // No return value
  #pragma warning (error:4715)        // Not all control paths return a value
  #pragma warning (error:4013)        // Call to undefined function
  #pragma warning (error:4700)        // Variable used before assignment
  #pragma warning (error:4701)        // Variable may be used before assignment
  #pragma warning (error:4005)        // Macro redefinition
  #pragma warning (error:4098)        // void function returns a value
  #pragma warning (error:4071)        // Call to unprototyped function
  #pragma warning (error:4072)        // Call to unprototyped function 
  #pragma warning (error:4020)        // Too many parameters
  #pragma warning (error:4554)        // Check operator precedence for possible error
  #pragma warning (error:4296)        // Expression is always false
  
  //
  // Subset of MSVC warnings disabled entirely
  //
  
  #pragma warning (disable:4100)      // unreferenced formal parameter
  #pragma warning (disable:4505)      // unreferenced local function
  #pragma warning (disable:4512)      // assignment operator could not be generated due to const/& member
  #pragma warning (disable:4702)      // unreachable code
  
  //
  // Enable a subset of off-by-default MSVC warnings 
  //
  
  #pragma warning (default:4777)      // format string type mismatch
  
  #endif
  
  #ifndef strlen
  #define strlen (int) strlen         // allow signed ints with strlen() without "size_t cast to 32-bit int" warning
  #endif
  
  #ifndef US_TYPEDEFS
  #define US_TYPEDEFS
  
  typedef unsigned char    U8 ;
  typedef unsigned short   U16;
  typedef unsigned int     U32;
  typedef          char    C8 ;
  typedef signed   char    S8 ;
  typedef signed   short   S16;
  typedef signed   int     S32;
  
  #ifdef _MSC_VER
  #if (_MSC_VER >= 1500)
    typedef uintptr_t        UINTa;
    typedef intptr_t         SINTa;
  #else
    typedef unsigned __int64 UINTa;
    typedef signed   __int64 SINTa;
  #endif
  #else
  #ifdef __AVR__
  typedef unsigned long long UINTa;
  typedef long long          SINTa;
  #else
  typedef unsigned __int64   UINTa;
  typedef signed   __int64   SINTa;
  #endif
  #endif
  
  #ifdef __cplusplus      // (define these in C++ only, for H2INC compatibility)
  #ifdef __AVR__
  typedef unsigned long long U64;
  typedef long long          S64;
  #else                       
  typedef unsigned __int64   U64;
  typedef signed   __int64   S64;
  #endif
  #endif
  
  #endif
  
  #ifndef F_TYPEDEFS
  #define F_TYPEDEFS
  
  typedef float            SINGLE;
  typedef float            F32;
  typedef double           DOUBLE;
  typedef double           F64;
  
  #endif
  
  #ifndef C_TYPEDEFS
  #define C_TYPEDEFS
  
  #ifndef FREE
  #define FREE(x) if ((x) != NULL) { free((x)); (x) = NULL; }
  #endif
  
  #ifndef ARY_CNT
  #define ARY_CNT(x) sizeof(x) / sizeof((x)[0])
  #endif
  
  #ifndef PI_DEFINED
  #define PI_DEFINED                  
  #ifndef PI
     static const DOUBLE PI          = 3.14159265358979323846;
  #endif
  #ifndef TWO_PI
     static const DOUBLE TWO_PI      = (2.0 * PI);
  #endif
     static const DOUBLE PI_OVER_TWO = (0.5 * PI);
     static const DOUBLE LN_TWO      = 0.69314718055994530942;
  
     #ifndef RAD2DEG_DEFINED
     #define RAD2DEG_DEFINED
        static const DOUBLE RAD2DEG = 180.0 / PI;
        static const DOUBLE DEG2RAD = PI / 180.0;
     #endif
  #endif
  
  #ifdef __cplusplus
  
  struct COMPLEX_DOUBLE      // No virtuals, so instances can be allocated with malloc() or new
  {
     DOUBLE real;
     DOUBLE imag;
  
     COMPLEX_DOUBLE(DOUBLE r, DOUBLE i) : real(r), imag(i)
        {
        }
  
     COMPLEX_DOUBLE(DOUBLE r) : real(r), imag(0.0)
        {
        }
  
     COMPLEX_DOUBLE() : real(0.0), imag(0.0)      // (allows { 0 } initialization to work)
        {
        }
  
  #ifdef _INC_MATH
     const DOUBLE cabs(void)
        {
        return hypot(real, imag);
        }
  
     static const DOUBLE cabs(COMPLEX_DOUBLE val)
        {
        return val.hypot();
        }
  
     static DOUBLE hypot(DOUBLE x, DOUBLE y)
        {
        x = fabs(x);
        y = fabs(y);
  
        if (x < 1E-30) return y;
        if (y < 1E-30) return x;
  
        DOUBLE t = (x < y) ? x : y;
        x = (x > y) ? x : y;
  
        t /= x;
  
        return x * sqrt(1.0 + (t*t));
        }
  
     const DOUBLE hypot(void)
        {
        return hypot(real, imag);
        }
  
     const DOUBLE carg(void)
        {
        return atan2(imag, real);
        }
  
     const DOUBLE cmag(void)
        {
        return sqrt(real*real+imag*imag);
        }
  
     const COMPLEX_DOUBLE cpow(COMPLEX_DOUBLE pwr)
        {
        if ((pwr.real == 0.0) && (pwr.imag == 0.0))
           {
           return COMPLEX_DOUBLE(1.0, 0.0);
           }
  
        if ((real == 0.0) && (imag == 0.0))
           {
           return COMPLEX_DOUBLE(0.0, 0.0);
           }
  
        DOUBLE vabs  = hypot(real, imag);
        DOUBLE len   = pow(vabs, pwr.real);
        DOUBLE at    = atan2(imag, real);
        DOUBLE phase = at * pwr.real;
  
        if (pwr.imag != 0.0)
           {
           len /= exp(at * pwr.imag);
           phase += pwr.imag * log(vabs);
           }
  
        return COMPLEX_DOUBLE(len * cos(phase), len * sin(phase));
        }
  
     static const COMPLEX_DOUBLE cpow(COMPLEX_DOUBLE val, COMPLEX_DOUBLE pwr)
        {
        return val.cpow(pwr);
        }
  
     const COMPLEX_DOUBLE csqrt(void)
        {
        return cpow(0.5);
        }
  
     static COMPLEX_DOUBLE csqrt(COMPLEX_DOUBLE val)
        {
        return val.csqrt();
        }
  #endif
  
     const COMPLEX_DOUBLE conj(void)
        {
        COMPLEX_DOUBLE temp;
  
        temp.real =  real;
        temp.imag = -imag;
  
        return temp;
        }
  
     const bool operator == (const COMPLEX_DOUBLE &c) const
        {
        return (real == c.real) && (imag == c.imag);
        }
  
     const COMPLEX_DOUBLE operator + (const COMPLEX_DOUBLE &c) const
        {
        COMPLEX_DOUBLE temp;
  
        temp.real = real + c.real;
        temp.imag = imag + c.imag;
  
        return temp;
        }
  
     const COMPLEX_DOUBLE operator - (const COMPLEX_DOUBLE &c) const
        {
        COMPLEX_DOUBLE temp;
  
        temp.real = real - c.real;
        temp.imag = imag - c.imag;
  
        return temp;
        }
  
     const COMPLEX_DOUBLE operator * (const COMPLEX_DOUBLE &c) const
        {
        COMPLEX_DOUBLE temp;
  
        temp.real = (real * c.real) - (imag * c.imag);
        temp.imag = (real * c.imag) + (imag * c.real);
  
        return temp;
        }
  
     const COMPLEX_DOUBLE operator / (const COMPLEX_DOUBLE &c) const
        {
        COMPLEX_DOUBLE temp;
  
        DOUBLE D = (c.real * c.real) + (c.imag * c.imag);
  
        temp.real = ((real * c.real) + (imag * c.imag)) / D;
        temp.imag = ((imag * c.real) - (real * c.imag)) / D;
  
        return temp;
        }
  
     const COMPLEX_DOUBLE operator + (const DOUBLE &c) const
        {
        COMPLEX_DOUBLE temp;
  
        temp.real = real + c;
        temp.imag = imag + c;
  
        return temp;
        }
  
     const COMPLEX_DOUBLE operator - (const DOUBLE &c) const
        {
        COMPLEX_DOUBLE temp;
  
        temp.real = real - c;
        temp.imag = imag - c;
  
        return temp;
        }
  
     const COMPLEX_DOUBLE operator * (const DOUBLE &c) const
        {
        COMPLEX_DOUBLE temp;
  
        temp.real = real * c;
        temp.imag = imag * c;
  
        return temp;
        }
  
     const COMPLEX_DOUBLE operator / (const DOUBLE &c) const
        {
        COMPLEX_DOUBLE temp;
  
        temp.real = real / c;
        temp.imag = imag / c;
  
        return temp;
        }
  };
  
  #else
  
  typedef struct _COMPLEX_DOUBLE
  {
     DOUBLE real;
     DOUBLE imag;
  }
  COMPLEX_DOUBLE;
  
  #endif
  #endif
  
  #ifndef YES
  #define YES 1
  #endif
  
  #ifndef NO
  #define NO  0
  #endif
  
  #ifndef TRUE
  #define TRUE 1
  #endif
  
  #ifndef FALSE
  #define FALSE  0
  #endif
  
  #ifdef ANSI_CONSOLE_COLORS
  #define AC_GRAY      "\x1b[01m\x1b[30m"
  #define AC_RED       "\x1b[01m\x1b[31m"
  #define AC_DKRED     "\x1b[00m\x1b[31m"
  #define AC_GREEN     "\x1b[01m\x1b[32m"
  #define AC_DKGREEN   "\x1b[00m\x1b[32m"
  #define AC_YELLOW    "\x1b[01m\x1b[33m"
  #define AC_DKYELLOW  "\x1b[00m\x1b[33m"
  #define AC_BLUE      "\x1b[01m\x1b[34m"
  #define AC_DKBLUE    "\x1b[00m\x1b[34m"
  #define AC_MAGENTA   "\x1b[01m\x1b[35m"
  #define AC_DKMAGENTA "\x1b[00m\x1b[35m"
  #define AC_CYAN      "\x1b[01m\x1b[36m"
  #define AC_DKCYAN    "\x1b[00m\x1b[36m"
  #define AC_WHITE     "\x1b[01m\x1b[37m"
  #define AC_DKWHITE   "\x1b[00m\x1b[37m"
  #define AC_RESET     "\x1b[01m\x1b[0m"
  #define AC_NORM      "\x1b[01m\x1b[0m"
  #define AC_NORMAL    "\x1b[01m\x1b[0m"
  #else
  #ifdef NO_ANSI_CONSOLE_COLORS
  #endif
  #define AC_GRAY      ""
  #define AC_RED       ""
  #define AC_DKRED     ""
  #define AC_GREEN     ""
  #define AC_DKGREEN   ""
  #define AC_YELLOW    ""
  #define AC_DKYELLOW  ""
  #define AC_BLUE      ""
  #define AC_DKBLUE    ""
  #define AC_MAGENTA   ""
  #define AC_DKMAGENTA ""
  #define AC_CYAN      ""
  #define AC_DKCYAN    ""
  #define AC_WHITE     ""
  #define AC_DKWHITE   ""
  #define AC_RESET     ""
  #define AC_NORM      ""
  #define AC_NORMAL    ""
  #endif
  
  #ifndef NO_BINARY_CONSTANTS
  #define B00000000 0
  #define B00000001 1
  #define B00000010 2
  #define B00000011 3
  #define B00000100 4
  #define B00000101 5
  #define B00000110 6
  #define B00000111 7
  #define B00001000 8
  #define B00001001 9
  #define B00001010 10
  #define B00001011 11
  #define B00001100 12
  #define B00001101 13
  #define B00001110 14
  #define B00001111 15
  #define B00010000 16
  #define B00010001 17
  #define B00010010 18
  #define B00010011 19
  #define B00010100 20
  #define B00010101 21
  #define B00010110 22
  #define B00010111 23
  #define B00011000 24
  #define B00011001 25
  #define B00011010 26
  #define B00011011 27
  #define B00011100 28
  #define B00011101 29
  #define B00011110 30
  #define B00011111 31
  #define B00100000 32
  #define B00100001 33
  #define B00100010 34
  #define B00100011 35
  #define B00100100 36
  #define B00100101 37
  #define B00100110 38
  #define B00100111 39
  #define B00101000 40
  #define B00101001 41
  #define B00101010 42
  #define B00101011 43
  #define B00101100 44
  #define B00101101 45
  #define B00101110 46
  #define B00101111 47
  #define B00110000 48
  #define B00110001 49
  #define B00110010 50
  #define B00110011 51
  #define B00110100 52
  #define B00110101 53
  #define B00110110 54
  #define B00110111 55
  #define B00111000 56
  #define B00111001 57
  #define B00111010 58
  #define B00111011 59
  #define B00111100 60
  #define B00111101 61
  #define B00111110 62
  #define B00111111 63
  #define B01000000 64
  #define B01000001 65
  #define B01000010 66
  #define B01000011 67
  #define B01000100 68
  #define B01000101 69
  #define B01000110 70
  #define B01000111 71
  #define B01001000 72
  #define B01001001 73
  #define B01001010 74
  #define B01001011 75
  #define B01001100 76
  #define B01001101 77
  #define B01001110 78
  #define B01001111 79
  #define B01010000 80
  #define B01010001 81
  #define B01010010 82
  #define B01010011 83
  #define B01010100 84
  #define B01010101 85
  #define B01010110 86
  #define B01010111 87
  #define B01011000 88
  #define B01011001 89
  #define B01011010 90
  #define B01011011 91
  #define B01011100 92
  #define B01011101 93
  #define B01011110 94
  #define B01011111 95
  #define B01100000 96
  #define B01100001 97
  #define B01100010 98
  #define B01100011 99
  #define B01100100 100
  #define B01100101 101
  #define B01100110 102
  #define B01100111 103
  #define B01101000 104
  #define B01101001 105
  #define B01101010 106
  #define B01101011 107
  #define B01101100 108
  #define B01101101 109
  #define B01101110 110
  #define B01101111 111
  #define B01110000 112
  #define B01110001 113
  #define B01110010 114
  #define B01110011 115
  #define B01110100 116
  #define B01110101 117
  #define B01110110 118
  #define B01110111 119
  #define B01111000 120
  #define B01111001 121
  #define B01111010 122
  #define B01111011 123
  #define B01111100 124
  #define B01111101 125
  #define B01111110 126
  #define B01111111 127
  #define B10000000 128
  #define B10000001 129
  #define B10000010 130
  #define B10000011 131
  #define B10000100 132
  #define B10000101 133
  #define B10000110 134
  #define B10000111 135
  #define B10001000 136
  #define B10001001 137
  #define B10001010 138
  #define B10001011 139
  #define B10001100 140
  #define B10001101 141
  #define B10001110 142
  #define B10001111 143
  #define B10010000 144
  #define B10010001 145
  #define B10010010 146
  #define B10010011 147
  #define B10010100 148
  #define B10010101 149
  #define B10010110 150
  #define B10010111 151
  #define B10011000 152
  #define B10011001 153
  #define B10011010 154
  #define B10011011 155
  #define B10011100 156
  #define B10011101 157
  #define B10011110 158
  #define B10011111 159
  #define B10100000 160
  #define B10100001 161
  #define B10100010 162
  #define B10100011 163
  #define B10100100 164
  #define B10100101 165
  #define B10100110 166
  #define B10100111 167
  #define B10101000 168
  #define B10101001 169
  #define B10101010 170
  #define B10101011 171
  #define B10101100 172
  #define B10101101 173
  #define B10101110 174
  #define B10101111 175
  #define B10110000 176
  #define B10110001 177
  #define B10110010 178
  #define B10110011 179
  #define B10110100 180
  #define B10110101 181
  #define B10110110 182
  #define B10110111 183
  #define B10111000 184
  #define B10111001 185
  #define B10111010 186
  #define B10111011 187
  #define B10111100 188
  #define B10111101 189
  #define B10111110 190
  #define B10111111 191
  #define B11000000 192
  #define B11000001 193
  #define B11000010 194
  #define B11000011 195
  #define B11000100 196
  #define B11000101 197
  #define B11000110 198
  #define B11000111 199
  #define B11001000 200
  #define B11001001 201
  #define B11001010 202
  #define B11001011 203
  #define B11001100 204
  #define B11001101 205
  #define B11001110 206
  #define B11001111 207
  #define B11010000 208
  #define B11010001 209
  #define B11010010 210
  #define B11010011 211
  #define B11010100 212
  #define B11010101 213
  #define B11010110 214
  #define B11010111 215
  #define B11011000 216
  #define B11011001 217
  #define B11011010 218
  #define B11011011 219
  #define B11011100 220
  #define B11011101 221
  #define B11011110 222
  #define B11011111 223
  #define B11100000 224
  #define B11100001 225
  #define B11100010 226
  #define B11100011 227
  #define B11100100 228
  #define B11100101 229
  #define B11100110 230
  #define B11100111 231
  #define B11101000 232
  #define B11101001 233
  #define B11101010 234
  #define B11101011 235
  #define B11101100 236
  #define B11101101 237
  #define B11101110 238
  #define B11101111 239
  #define B11110000 240
  #define B11110001 241
  #define B11110010 242
  #define B11110011 243
  #define B11110100 244
  #define B11110101 245
  #define B11110110 246
  #define B11110111 247
  #define B11111000 248
  #define B11111001 249
  #define B11111010 250
  #define B11111011 251
  #define B11111100 252
  #define B11111101 253
  #define B11111110 254
  #define B11111111 255
  #endif
  
  //
  // Quick and dirty memory leak detection
  //
  
  #ifdef MEMDEBUG
  #ifdef __cplusplus
  
  struct MDHDR
  {
     char           file[256];
     int            line;
     size_t         num;
     size_t         size;
  
     void          *user;
     struct MDHDR **link;
  };
  
  static const int MAX_MDH = 65536;
  static MDHDR *MDH[MAX_MDH];
  
  struct MDHDUMP
  {
     ~MDHDUMP()
        {
        for (int i=0; i < MAX_MDH; i++)
           {
           MDHDR *H = MDH[i];
           if (H == NULL) continue;
  
           printf("%s %d: %d bytes leaked\n", H->file, H->line, (int) (H->num * H->size));
           }
        }
  };
  
  static MDHDUMP MDH_dump;
  
  void *MDH_alloc(size_t num, size_t size, bool clear, char const *file, int line)
  {
     size_t bytes = num*size;
  
     bytes += sizeof(MDHDR);
  
     void *entry = (void *) malloc(bytes);
     assert(entry);
  
     if (clear)
        {
        memset(entry, 0, bytes);
        }
  
     MDHDR *H = (MDHDR *) entry;
     memset(H, 0, sizeof(*H));
  
     _snprintf(H->file,sizeof(H->file)-1,"%s",file);
     H->line = line;
  
     H->user = (void *) ((U8 *) entry + sizeof(MDHDR));
  
     H->num = num;
     H->size = size;
  
     for (int i=0; i < MAX_MDH; i++)
        {
        if (MDH[i] == NULL)
           {
           H->link = &MDH[i];
           break;
           }
        }
  
     if (H->link != NULL)
        {
        *H->link = H;
        }
  
     return H->user;
  }
  
  void MDH_free(void *user)
  {
     MDHDR *H = ((MDHDR *) user) - 1;
  
     if (H->link != NULL)
        {
        assert(*H->link == H);
        *H->link = NULL;
        }
  
     free(H);
  }
  
  #define DBG_CALLOC(x,y) MDH_alloc(x, y, true,  __FILE__, __LINE__)
  #define DBG_MALLOC(x)   MDH_alloc(x, 1, false, __FILE__, __LINE__)
  
  #undef calloc
  #undef malloc
  #undef free
  
  #define calloc(x,y)  DBG_CALLOC(x,y)
  #define malloc(x)    DBG_MALLOC(x)
  #define free(x)      MDH_free(x)
  
  void *operator new(size_t size, char const *file, int line)
  {
     return MDH_alloc(size, 1, true, file, line);
  }
  
  void *operator new(size_t size)    
  {
     return MDH_alloc(size, 1, false, __FILE__, __LINE__);
  }
  
  void operator delete(void *user)
  {
     MDH_free(user);
  }
  
  #undef new
  #define new new(__FILE__, __LINE__)
  
  #endif
  #endif
  
  