/******************************************/
/*                                        */
/*    RenderWare(TM) Graphics Library     */
/*                                        */
/******************************************/

/*
 * This file is a product of Criterion Software Ltd.
 *
 * This file is provided as is with no warranties of any kind and is
 * provided without any obligation on Criterion Software Ltd.
 * or Canon Inc. to assist in its use or modification.
 *
 * Criterion Software Ltd. and Canon Inc. will not, under any
 * circumstances, be liable for any lost revenue or other damages
 * arising from the use of this file.
 *
 * Copyright (c) 1999. Criterion Software Ltd.
 * All Rights Reserved.
 */

/*************************************************************************
 *
 * Filename: <E:/nightly/rwsdk/include/sky2/rwcore.h>
 * Automatically Generated on: Tue Aug 21 11:29:23 2001
 *
 ************************************************************************/

#ifndef RWCORE_H
#define RWCORE_H

/*--- System Header Files ---*/
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>


/*--- Automatically derived from: E:/nightly/rwsdk/driver/common/barwasmm.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/devprofile.h ---*/
#if (!defined(RXPIPELINE))
#define RXPIPELINE
#endif /* (!defined(RXPIPELINE)) */

/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/skygeneric.h ---*/

// Enums
#ifndef vuEnumLightNaLight
// Warning these must be reconciled with the C enums.
// Check auto-generated file "baequate.i"

#define vuEnumLightNaLight 0      // rpNALIGHTTYPE
#define vuEnumLightDirectional 1  // rpLIGHTDIRECTIONAL
#define vuEnumLightAmbient 2      // rpLIGHTAMBIENT
#define vuEnumLightPoint 128      // rpLIGHTPOINT
#define vuEnumLightSpot 129       // rpLIGHTSPOT
#define vuEnumLightSpotSoft 130   // rpLIGHTSPOTSOFT

#endif

// Use this define to get a VUCONTINUE style lib. You must also define
// VUCONTINUE in world/pipe/p2/sky2/nodePS2MatInstance.h
// and world/pipe/p2/sky2/nodePS2All.h

// #define VUCONTINUE 1

// Data in high memory

#ifndef vuSDmat0

#define vuSDLightOffset     0x3d0
#define vuSDBlockLow        0x3c3
#define vuSDBlockHigh       0x3f0
#define vuSDmat0            vuSDBlockHigh
#define vuSDmat1            vuSDBlockHigh+1
#define vuSDmat2            vuSDBlockHigh+2
#define vuSDmat3            vuSDBlockHigh+3
#define vuSDnearClip        vuSDBlockHigh+4
#define vuSDfarClip         vuSDBlockHigh+5
#define vuSDxMaxyMax        vuSDBlockHigh+6
#define vuSDcamWcamHzScale  vuSDBlockHigh+7
#define vuSDoffXoffYzShift  vuSDBlockHigh+8
#define vuSDrealOffset      vuSDBlockHigh+9
#define vuSDgifTag          vuSDBlockHigh+10
#define vuSDcolScale        vuSDBlockHigh+11
#define vuSDsurfProps       vuSDBlockHigh+12
#define vuSDpingPongAddr    vuSDBlockHigh+13    
#define vuSDpingPongCount   vuSDBlockHigh+14    
#define vuSDClipvec1        vuSDBlockHigh+13                                     
#define vuSDClipvec2        vuSDBlockHigh+14                                        
#define vuSDVUSwitch        vuSDBlockHigh+15     

#endif

/*----------------- BUFFERS STRIDE -------------------------------------*/
#define _rwskyStrideOfInputCluster  (4)
#define _rwskyStrideOfOutputCluster (3)
/*----------------------------------------------------------------------*/

/*----------------- DOUBLE BUFFER --------------------------------------*/
#define _rwskyStaticDataStart       vuSDLightOffset
/*----------------------------------------------------------------------*/

/*----------------- BUFFERS SIZE ---------------------------------------*/
#define _rwskyTSVertexCount ((_rwskyStaticDataStart-2)/(2*_rwskyStrideOfInputCluster+2*_rwskyStrideOfOutputCluster))
#define _rwskyVIFOffset     (_rwskyStrideOfInputCluster*_rwskyTSVertexCount)
#define _rwskyTLTriCount    (_rwskyTSVertexCount/3)
/*----------------------------------------------------------------------*/



/*--- Automatically derived from: E:/nightly/rwsdk/os/sky/ostypes.h ---*/
#ifndef SKY_OSTYPES_H
#define SKY_OSTYPES_H

#define rwLITTLEENDIAN         /* This is a little endian machine */

#include <eetypes.h>
#include <../gcc/ee/include/string.h>  /* prototypes for memcpy etc */

typedef int RwFixed;
typedef int RwInt32;
typedef unsigned int RwUInt32;
typedef short RwInt16;
typedef unsigned short RwUInt16;
typedef unsigned char RwUInt8;
typedef signed char RwInt8;

#ifdef RWUNICODE
typedef wchar_t RwChar;
#else /* RWUNICODE */
typedef char RwChar;
#endif /* RWUNICODE */
typedef float RwReal;
typedef RwInt32 RwBool;

/*
 * Fix for GCC 2.95.3
 * From README_SN2953.txt:
 * Version 1.00 - March '01
 * ------------
 * CAUTION - With this patch the GNU 'long long' type should not be used - 
 * use 'long' instead (it is also 64bits).
 */

#if (defined(__GNUC__) && defined (__LONG_MAX__))
#if ( 2147483647L < __LONG_MAX__)
typedef long RwInt64;
typedef unsigned long RwUInt64;
#else  /* ( 2147483647L < __LONG_MAX__ ) */
typedef long long RwInt64;
typedef unsigned long long RwUInt64;
#endif /* ( 2147483647L < __LONG_MAX__ ) */
#else  /* (defined(__GNUC__) && defined (__LONG_MAX__)) */
typedef long long RwInt64;
typedef unsigned long long RwUInt64;
#endif /* (defined(__GNUC__) && defined (__LONG_MAX__)) */

#define RWZERO64 ((RwUInt64)0)

typedef long128 RwInt128;
typedef u_long128 RwUInt128;
#define RWZERO128 ((RwUInt128)0)

/* Limits of types */
#define RwInt32MAXVAL       0x7FFFFFFF
#define RwInt32MINVAL       0x80000000
#define RwUInt32MAXVAL      0xFFFFFFFF
#define RwUInt32MINVAL      0x00000000
#define RwRealMAXVAL        (RwReal)(3.40282347e+38)
#define RwRealMINVAL        (RwReal)(1.17549435e-38)
#define RwInt16MAXVAL       0x7FFF
#define RwInt16MINVAL       0x8000
#define RwUInt16MAXVAL      0xFFFF
#define RwUInt16MINVAL      0x0000

/* Structure alignment */
#define RWALIGN(type, x)   type __attribute__((aligned(x)))

/* Stringification */

#define _SKY_STRINGIFY(_x) #_x
#define _SKY_EXPAND(_x) _SKY_STRINGIFY(_x)

#if defined (__MWERKS__)

#if (defined(RWVERBOSE))
#pragma message (__FILE__ "/" _SKY_EXPAND(__LINE__) ": __MWERKS__ == " _SKY_EXPAND(__MWERKS__))
#endif /* (defined (__MWERKS__)) */

#if ((!defined(RWSUPPRESSOPTIMIZATIONPRAGMAS)) && __option(global_optimizer))

/* #pragma inline_instrinsics on */
/* #pragma always_inline on */ /* seems to hang the compiler sometimes  */

#pragma auto_inline on
#pragma dont_inline off
#pragma inline_depth(smart)
#pragma opt_common_subs on
#pragma opt_dead_assignments on
#pragma opt_dead_code on
#pragma opt_lifetimes on
#pragma opt_loop_invariants on
#pragma opt_propagation on
#pragma opt_strength_reduction on
#pragma opt_unroll_loops on
#pragma opt_vectorize_loops on
#pragma peephole on

#if (0x2401 <= __MWERKS__)
#pragma fast_fptosi on
#pragma irocseglobaladdresses on
#endif /* (0x2401 <= __MWERKS__) */

#endif /* ((!defined(RWSUPPRESSOPTIMIZATIONPRAGMAS)) && __option(global_optimizer)) */

#if (defined(RW_USE_SPF))
#pragma float_constants on
#endif /* (defined(RW_USE_SPF)) */

#pragma extended_errorcheck on

#define rwMATRIXALIGNMENT 16
#define rwFRAMEALIGNMENT 16
#define rwV4DALIGNMENT 16

#endif /*  defined (__MWERKS__) */

#if (!defined(rwMATRIXALIGNMENT))
#define rwMATRIXALIGNMENT sizeof(RwUInt128)
#endif /* (!defined(rwMATRIXALIGNMENT)) */

#if (!defined(rwFRAMEALIGNMENT))
#define rwFRAMEALIGNMENT sizeof(RwUInt128)
#endif /* (!defined(rwFRAMEALIGNMENT)) */

#if (!defined(rwV4DALIGNMENT))
#define rwV4DALIGNMENT sizeof(RwUInt128)
#endif /* (!defined(rwV4DALIGNMENT)) */

#endif /* SKY_OSTYPES_H */


/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/gs.h ---*/

/* Set of #defines to make the gs code more readable */

/* General purpose registers */
#define GS_PRIM     0x00
#define GS_RGBAQ    0x01
#define GS_ST       0x02
#define GS_UV       0x03
#define GS_XYZF2    0x04
#define GS_XYZ2     0x05
#define GS_TEX0_1   0x06
#define GS_TEX0_2   0x07
#define GS_CLAMP_1  0x08
#define GS_CLAMP_2  0x09
#define GS_FOG      0x0a
#define GS_XYZF3    0x0c
#define GS_XYZ3     0x0d
#define GS_TEX1_1   0x14
#define GS_TEX1_2   0x15
#define GS_TEX2_1   0x16
#define GS_TEX2_2   0x17
#define GS_XYOFFSET_1   0x18
#define GS_XYOFFSET_2   0x19
#define GS_PRMODECONT   0x1a
#define GS_PRMODE   0x1b
#define GS_TEXCLUT  0x1c
#define GS_SCANMSK  0x22
#define GS_MIPTBP1_1    0x34
#define GS_MIPTBP1_2    0x35
#define GS_MIPTBP2_1    0x36
#define GS_MIPTBP2_2    0x37
#define GS_TEXA     0x3b
#define GS_FOGCOL   0x3d
#define GS_TEXFLUSH 0x3f
#define GS_SCISSOR_1    0x40
#define GS_SCISSOR_2    0x41
#define GS_ALPHA_1  0x42
#define GS_ALPHA_2  0x43
#define GS_DIMX     0x44
#define GS_DTHE     0x45
#define GS_COLCLAMP 0x46
#define GS_TEST_1   0x47
#define GS_TEST_2   0x48
#define GS_PABE     0x49
#define GS_FBA_1    0x4a
#define GS_FBA_2    0x4b
#define GS_FRAME_1  0x4c
#define GS_FRAME_2  0x4d
#define GS_ZBUF_1   0x4e
#define GS_ZBUF_2   0x4f
#define GS_BITBLTBUF    0x50
#define GS_TRXPOS   0x51
#define GS_TRXREG   0x52
#define GS_TRXDIR   0x53
#define GS_HWREG    0x54
#define GS_SIGNAL   0x60
#define GS_FINISH   0x61
#define GS_LABEL    0x62
/*  Only present in sim */
#define GS_RFSHWIN  0x7f

/*  pixel modes */
#define PSMCT32     0x00
#define PSMCT24     0x01
#define PSMCT16     0x02
#define PSMCT16S    0x0a
#define PSMT8       0x13
#define PSMT4       0x14
#define PSMT8H      0x1b
#define PSMT4HL     0x24
#define PSMT4HH     0x2c
#define PSMZ32      0x30
#define PSMZ24      0x31
#define PSMZ16      0x32
#define PSMZ16S     0x3a

/* Note that in PSMCT16, PDMZ16 mode, only PSMZ16 zbuffers may be configured
   In all other modes only PSMZ16 zbuffers may not be configured */

#if (!defined(RXPIPELINE))
#define RXPIPELINE
#endif /* (!defined(RXPIPELINE)) */

/*--- Automatically derived from: E:/nightly/rwsdk/src/bamath.h ---*/

/****************************************************************************
 Defines
 */

/*
 * Ensure inclusion of prototypes for single precison maths functions
 * e.g. from
 * /usr/local/sce/ee/gcc/ee/include/math.h
 * /Program Files/Intel/Compiler4.0/include/mathf.h
 */

#if (defined(__KATANA__))

#include <mathf.h>

#else /* (defined(__KATANA__)) */

#if (defined(__ICL))

#if (defined(RWVERBOSE))

/*
 * See
 * http://www.eskimo.com/~scs/C-faq/q11.17.html
 */

#define _STRINGIFY(X) #X
#define _STRINGIFY_EXP(X) _STRINGIFY(X)

#pragma message ("Intel Compiler Version " _STRINGIFY_EXP(__ICL) ":" __FILE__ "(" _STRINGIFY_EXP(__LINE__) ")\n")
#pragma comment ( user, "comment:" "Intel Compiler Version " _STRINGIFY_EXP(__ICL) ":" __FILE__ "(" _STRINGIFY_EXP(__LINE__) ")\n")

#endif /* (defined(RWVERBOSE)) */

#if (400 < __ICL)
#if (defined(__cplusplus))
#define _INC_MATH
#endif /* (defined(__cplusplus)) */
#include <mathf.h>
#else /* (400 < __ICL) */
#undef RW_USE_SPF
#endif /* (400 < __ICL) */

#endif /* (defined(__ICL)) */

#include <math.h>

#endif /* !(defined(__KATANA__)) */

#define   _RW_C1      ( (float) 4.1666667908e-02 )
#define   _RW_C2      ( (float)-1.3888889225e-03 )
#define   _RW_C3      ( (float) 2.4801587642e-05 )
#define   _RW_C4      ( (float)-2.7557314297e-07 )
#define   _RW_C5      ( (float) 2.0875723372e-09 )
#define   _RW_C6      ( (float)-1.1359647598e-11 )
#define   _RW_S1      ( (float)-1.6666667163e-01 )
#define   _RW_S2      ( (float) 8.3333337680e-03 )
#define   _RW_S3      ( (float)-1.9841270114e-04 )
#define   _RW_S4      ( (float) 2.7557314297e-06 )
#define   _RW_S5      ( (float)-2.5050759689e-08 )
#define   _RW_S6      ( (float) 1.5896910177e-10 )
#define   _RW_one     ( (float) 1.0000000000e+00 )
#define   _RW_pS0     ( (float) 1.6666667163e-01 )
#define   _RW_pS1     ( (float)-3.2556581497e-01 )
#define   _RW_pS2     ( (float) 2.0121252537e-01 )
#define   _RW_pS3     ( (float)-4.0055535734e-02 )
#define   _RW_pS4     ( (float) 7.9153501429e-04 )
#define   _RW_pS5     ( (float) 3.4793309169e-05 )
#define   _RW_pi      ( (float) 3.1415925026e+00 )
#define   _RW_pi_tol  ( (float) 0.0312500000e+00 )
#define   _RW_pio2_hi ( (float) 1.5707962513e+00 )
#define   _RW_pio2_lo ( (float) 7.5497894159e-08 )
#define   _RW_qS1     ( (float)-2.4033949375e+00 )
#define   _RW_qS2     ( (float) 2.0209457874e+00 )
#define   _RW_qS3     ( (float)-6.8828397989e-01 )
#define   _RW_qS4     ( (float) 7.7038154006e-02 )

#define RwCosMinusPiToPiMacro(result, x)                          \
MACRO_START                                                       \
{                                                                 \
    const float z = x * x;                                        \
    const float r = ( z * (_RW_C1  +                              \
                           z * (_RW_C2  +                         \
                                z * (_RW_C3  +                    \
                                     z * (_RW_C4  +               \
                                          z * (_RW_C5  +          \
                                               z * _RW_C6))))));  \
    result = (_RW_one - ((float) 0.5 * z - (z * r )));            \
}                                                                 \
MACRO_STOP

#define RwSinMinusPiToPiMacro(result, x)                          \
do                                                                \
{                                                                 \
    const float z = x * x;                                        \
    const float v = z * x;                                        \
    const float r = ( _RW_S2 +                                    \
                      z * (_RW_S3 +                               \
                           z * (_RW_S4 +                          \
                                z * (_RW_S5 +                     \
                                     z * _RW_S6))) );             \
    result = x + v * (_RW_S1 + z * r);                            \
}                                                                 \
while(0)                                                                  

typedef union _rwIEEEFloatShapeType _rwIEEEFloatShapeType;
union _rwIEEEFloatShapeType
{
    float               value;
    unsigned int        word;
};

#define _RW_GET_FLOAT_WORD(i,d)                 \
do {                                            \
  _rwIEEEFloatShapeType gf_u;                   \
  gf_u.value = (d);                             \
  (i) = gf_u.word;                              \
} while (0)

/* Set a float from a 32 bit int.  */

#define _RW_SET_FLOAT_WORD(d,i)                 \
do {                                            \
  _rwIEEEFloatShapeType sf_u;                   \
  sf_u.word = (i);                              \
  (d) = sf_u.value;                             \
} while (0)

#define RwIEEEACosfMacro(result, x)                                      \
do                                                                       \
{                                                                        \
    float               z, p, q, r, w, s, c, df;                         \
    int                 hx, ix;                                          \
                                                                         \
    _RW_GET_FLOAT_WORD(hx, x);                                           \
    ix = hx & 0x7fffffff;                                                \
    if (ix >= 0x3f800000)                                                \
    {                          /* |x|>=1 */                              \
        if (hx > 0)                                                      \
        {                                                                \
            /* acos(1) = 0  */                                           \
            result = (0.0);                                              \
        }                                                                \
        else                                                             \
        {                                                                \
            /* acos(-1)= _RW_pi */                                       \
            result = (_RW_pi + (float) 2.0 * _RW_pio2_lo);               \
        }                                                                \
                                                                         \
    }                                                                    \
    else if (ix < 0x3f000000)                                            \
    {                          /* |x| < 0.5 */                           \
        if (ix <= 0x23000000)                                            \
        {                                                                \
            /*if |x|<2**-57 */                                           \
            result = (_RW_pio2_hi + _RW_pio2_lo);                        \
        }                                                                \
        else                                                             \
        {                                                                \
            z = x * x;                                                   \
            p = z * (_RW_pS0 +                                           \
                     z * (_RW_pS1 +                                      \
                          z * (_RW_pS2 +                                 \
                               z * (_RW_pS3 +                            \
                                    z * (_RW_pS4 + z * _RW_pS5)))));     \
            q = _RW_one + z * (_RW_qS1 +                                 \
                               z * (_RW_qS2 +                            \
                                    z * (_RW_qS3 + z * _RW_qS4)));       \
            r = p / q;                                                   \
            result = (_RW_pio2_hi - (x - (_RW_pio2_lo - x * r)));        \
        }                                                                \
                                                                         \
    }                                                                    \
    else if (hx < 0)                                                     \
    {                          /* x < -0.5 */                            \
        z = (_RW_one + x) * (float) 0.5;                                 \
        p = z * (_RW_pS0 +                                               \
                 z * (_RW_pS1 +                                          \
                      z * (_RW_pS2 +                                     \
                           z * (_RW_pS3 +                                \
                                z * (_RW_pS4 + z * _RW_pS5)))));         \
        q = _RW_one + z * (_RW_qS1 +                                     \
                           z * (_RW_qS2 + z * (_RW_qS3 + z * _RW_qS4))); \
        rwSqrtMacro(s, z);                                               \
        r = p / q;                                                       \
        w = r * s - _RW_pio2_lo;                                         \
        result = (_RW_pi - (float) 2.0 * (s + w));                       \
    }                                                                    \
    else                                                                 \
    {                          /* x > 0.5 */                             \
        int                 idf;                                         \
                                                                         \
        z = (_RW_one - x) * (float) 0.5;                                 \
        rwSqrtMacro(s, z);                                               \
        df = s;                                                          \
        _RW_GET_FLOAT_WORD(idf, df);                                     \
        _RW_SET_FLOAT_WORD(df, idf & 0xfffff000);                        \
        c = (z - df * df) / (s + df);                                    \
        p = z * (_RW_pS0 +                                               \
                 z * (_RW_pS1 +                                          \
                      z * (_RW_pS2 +                                     \
                           z * (_RW_pS3 +                                \
                                z * (_RW_pS4 + z * _RW_pS5)))));         \
        q = _RW_one + z * (_RW_qS1 +                                     \
                           z * (_RW_qS2 + z * (_RW_qS3 + z * _RW_qS4))); \
        r = p / q;                                                       \
        w = r * s + c;                                                   \
        result = ((float) 2.0 * (df + w));                               \
    }                                                                    \
}                                                                        \
while(0)

#if (defined(RW_USE_SPF))

#define RwACos(_x)              acosf(_x)
#define RwACosh(_x)             acoshf(_x)
#define RwASin(_x)              asinf(_x)
#define RwASinh(_x)             asinhf(_x)

#if (!defined(__ICL))
/*
 * No SPF version in
 * Program Files/Intel/compilerXXX/include/mathf.h
 * of atan2()
 */
#define RwATan2(_x, _y)         atan2f(_x, _y)
#endif /* (!defined(__ICL)) */

#define RwATan(_x)              atanf(_x)
#define RwATanh(_x)             atanhf(_x)
#define RwCabs()                cabsf()
#define RwCbrt(_x)              cbrtf(_x)
#define RwCeil(_x)              ceilf(_x)
#define RwCopysign(_x, _y)      copysignf(_x, _y)
#define RwCos(_x)               cosf(_x)
#define RwCosh(_x)              coshf(_x)
#define RwDrem(_x, _y)          dremf(_x, _y)
#define RwErfc(_x)              erfcf(_x)
#define RwErf(_x)               erff(_x)
#define RwExp(_x)               expf(_x)
#define RwExpm1(_x)             expm1f(_x)
#define RwFinite(_x)            finitef(_x)
#define RwIlogb(_x)             ilogbf(_x)
#define RwIsinf(_x)             isinff(_x)
#define RwIsnan(_x)             isnanf(_x)
#define RwFabs(_x)              fabsf(_x)
#define RwFloor(_x)             floorf(_x)
#define RwFmod(_x, _y)          fmodf(_x, _y)
#define RwFrexp(_x, _iptr)      frexpf(_x, _iptr)
#define RwGamma(_x)             gammaf(_x)
#define RwGammaf_(_x, _iptr)    gammaf_r(_x, _iptr)
#define RwHypot(_x, _y)         hypotf(_x, _y)
#define RwInfinity()            infinityf()
#define RwJ0(_x)                j0f(_x)
#define RwJ1(_x)                j1f(_x)
#define RwJn(_i, _x)            jnf(_i, _x)
#define RwLdexp(_x, _i)         ldexpf(_x, _i)
#define RwLgamma(_x)            lgammaf(_x)
#define RwLgammaf_(_x, _iptr)   lgammaf_r(_x, _iptr)
#define RwLog10(_x)             log10f(_x)
#define RwLog1p(_x)             log1pf(_x)
#define RwLog(_x)               logf(_x)
#define RwModf(_x, _y)          modff(_x, _y)
#define RwNan()                 nanf()
#define RwNextafter(_x, _y)     nextafterf(_x, _y)
#define RwPow(_x, _y)           powf(_x, _y)
#define RwRemainder(_x, _y)     remainderf(_x, _y)
#define RwRint(_x)              rintf(_x)
#define RwScalbn(_x, _i)        scalbnf(_x, _i)
#define RwSin(_x)               sinf(_x)
#define RwSinh(_x)              sinhf(_x)
#define rwSqrt(_x)              sqrtf(_x)
#define RwTan(_x)               tanf(_x)
#define RwTanh(_x)              tanhf(_x)
#define RwY0(_x)                y0f(_x)
#define RwY1(_x)                y1f(_x)
#define RwYn(_i, _x)            ynf(_i, _x)

#endif /* (defined(RW_USE_SPF)) */

#if (!defined(RwACos))
#define RwACos(_x)              acos(_x)
#endif /* (!defined(RwACos)) */
#if (!defined(RwACosh))
#define RwACosh(_x)             acosh(_x)
#endif /* (!defined(RwACosh)) */
#if (!defined(RwASin))
#define RwASin(_x)              asin(_x)
#endif /* (!defined(RwASin)) */
#if (!defined(RwASinh))
#define RwASinh(_x)             asinh(_x)
#endif /* (!defined(RwASinh)) */
#if (!defined(RwATan2))
#define RwATan2(_x, _y)         atan2(_x, _y)
#endif /* (!defined(RwATan2)) */
#if (!defined(RwATan))
#define RwATan(_x)              atan(_x)
#endif /* (!defined(RwATan)) */
#if (!defined(RwATanh))
#define RwATanh(_x)             atanh(_x)
#endif /* (!defined(RwATanh)) */
#if (!defined(RwCabs))
#define RwCabs()                cabs()
#endif /* (!defined(RwCabs)) */
#if (!defined(RwCbrt))
#define RwCbrt(_x)              cbrt(_x)
#endif /* (!defined(RwCbrt)) */
#if (!defined(RwCeil))
#define RwCeil(_x)              ceil(_x)
#endif /* (!defined(RwCeil)) */
#if (!defined(RwCopysign))
#define RwCopysign(_x, _y)      copysign(_x, _y)
#endif /* (!defined(RwCopysign)) */
#if (!defined(RwCos))
#define RwCos(_x)               cos(_x)
#endif /* (!defined(RwCos)) */
#if (!defined(RwCosh))
#define RwCosh(_x)              cosh(_x)
#endif /* (!defined(RwCosh)) */
#if (!defined(RwDrem))
#define RwDrem(_x, _y)          drem(_x, _y)
#endif /* (!defined(RwDrem)) */
#if (!defined(RwErfc))
#define RwErfc(_x)              erfc(_x)
#endif /* (!defined(RwErfc)) */
#if (!defined(RwEr))
#define RwEr(_x)               erf(_x)
#endif /* (!defined(RwEr)) */
#if (!defined(RwExp))
#define RwExp(_x)               exp(_x)
#endif /* (!defined(RwExp)) */
#if (!defined(RwExpm1))
#define RwExpm1(_x)             expm1(_x)
#endif /* (!defined(RwExpm1)) */
#if (!defined(RwFinite))
#define RwFinite(_x)            finite(_x)
#endif /* (!defined(RwFinite)) */
#if (!defined(RwIlogb))
#define RwIlogb(_x)             ilogb(_x)
#endif /* (!defined(RwIlogb)) */
#if (!defined(RwIsin))
#define RwIsin(_x)             isinf(_x)
#endif /* (!defined(RwIsin)) */
#if (!defined(RwIsnan))
#define RwIsnan(_x)             isnan(_x)
#endif /* (!defined(RwIsnan)) */
#if (!defined(RwFabs))
#define RwFabs(_x)              fabs(_x)
#endif /* (!defined(RwFabs)) */
#if (!defined(RwFloor))
#define RwFloor(_x)             floor(_x)
#endif /* (!defined(RwFloor)) */
#if (!defined(RwFmod))
#define RwFmod(_x, _y)          fmod(_x, _y)
#endif /* (!defined(RwFmod)) */
#if (!defined(RwFrexp))
#define RwFrexp(_x, _iptr)      frexp(_x, _iptr)
#endif /* (!defined(RwFrexp)) */
#if (!defined(RwGamma))
#define RwGamma(_x)             gamma(_x)
#endif /* (!defined(RwGamma)) */
#if (!defined(RwGammaf_))
#define RwGammaf_(_x, _iptr)    gammaf_r(_x, _iptr)
#endif /* (!defined(RwGammaf_)) */
#if (!defined(RwHypot))
#define RwHypot(_x, _y)         hypot(_x, _y)
#endif /* (!defined(RwHypot)) */
#if (!defined(RwInfinity))
#define RwInfinity()            infinity()
#endif /* (!defined(RwInfinity)) */
#if (!defined(RwJ0))
#define RwJ0(_x)                j0(_x)
#endif /* (!defined(RwJ0)) */
#if (!defined(RwJ1))
#define RwJ1(_x)                j1(_x)
#endif /* (!defined(RwJ1)) */
#if (!defined(RwJn))
#define RwJn(_i, _x)            jn(_i, _x)
#endif /* (!defined(RwJn)) */
#if (!defined(RwLdexp))
#define RwLdexp(_x, _i)         ldexp(_x, _i)
#endif /* (!defined(RwLdexp)) */
#if (!defined(RwLgamma))
#define RwLgamma(_x)            lgamma(_x)
#endif /* (!defined(RwLgamma)) */
#if (!defined(RwLgammaf_))
#define RwLgammaf_(_x, _iptr)   lgammaf_r(_x, _iptr)
#endif /* (!defined(RwLgammaf_)) */
#if (!defined(RwLog10))
#define RwLog10(_x)             log10(_x)
#endif /* (!defined(RwLog10)) */
#if (!defined(RwLog1p))
#define RwLog1p(_x)             log1p(_x)
#endif /* (!defined(RwLog1p)) */
#if (!defined(RwLog))
#define RwLog(_x)               log(_x)
#endif /* (!defined(RwLog)) */
#if (!defined(RwMod))
#define RwMod(_x, _y)           mod(_x, _y )
#endif /* (!defined(RwMod)) */
#if (!defined(RwNan))
#define RwNan()                 nan()
#endif /* (!defined(RwNan)) */
#if (!defined(RwNextafter))
#define RwNextafter(_x, _y)     nextafter(_x, _y)
#endif /* (!defined(RwNextafter)) */
#if (!defined(RwPow))
#define RwPow(_x, _y)           pow(_x, _y)
#endif /* (!defined(RwPow)) */
#if (!defined(RwRemainder))
#define RwRemainder(_x, _y)     remainder(_x, _y)
#endif /* (!defined(RwRemainder)) */
#if (!defined(RwRint))
#define RwRint(_x)              rint(_x)
#endif /* (!defined(RwRint)) */
#if (!defined(RwScalbn))
#define RwScalbn(_x, _i)        scalbn(_x, _i)
#endif /* (!defined(RwScalbn)) */
#if (!defined(RwSin))
#define RwSin(_x)               sin(_x)
#endif /* (!defined(RwSin)) */
#if (!defined(RwSinh))
#define RwSinh(_x)              sinh(_x)
#endif /* (!defined(RwSinh)) */
#if (!defined(rwSqrt))
#define rwSqrt(_x)              sqrt(_x)
#endif /* (!defined(rwSqrt)) */
#if (!defined(RwTan))
#define RwTan(_x)               tan(_x)
#endif /* (!defined(RwTan)) */
#if (!defined(RwTanh))
#define RwTanh(_x)              tanh(_x)
#endif /* (!defined(RwTanh)) */
#if (!defined(RwY0))
#define RwY0(_x)                y0(_x)
#endif /* (!defined(RwY0)) */
#if (!defined(RwY1))
#define RwY1(_x)                y1(_x)
#endif /* (!defined(RwY1)) */
#if (!defined(RwYn))
#define RwYn(_i, _x)            yn(_i, _x)
#endif /* (!defined(RwYn)) */


/*--- Automatically derived from: E:/nightly/rwsdk/src/batypes.h ---*/

#define rwLIBRARYBASEVERSION    0x301 /* 3.01 */
#define rwLIBRARYCURRENTVERSION (rwLIBRARYBASEVERSION+0x0F) /* 3.10 */

/* IMPORTANT:
 * The following Doxygen comment MUST be copied into RwCore.h,
 * so don't move it from here. */

/**
 * \ingroup rwcore
 * \page rwcoreoverview Core Library Overview
 *
 * LIBRARY: rwcore.lib
 * HEADER: rwcore.h
 *
 * This library provides the fundamental RenderWare Graphics features.
 *
 * When creating a RenderWare application, this library must always be
 * linked.
 *
 * Functionality includes:
 * \li Immediate Modes (2D \ref rwim2d and 3D \ref rwim3d )
 * \li Plugin Management
 * \li Base Datatypes
 * \li Cameras \ref rwcamera
 * \li Frames \ref rwframe
 * \li the RenderWare Engine \ref rwengine
 *
 * RenderWare uses an object-oriented design philosophy, so this
 * documentation is split across a number of objects.
 *
 * These objects are implemented in C, so C terminology is generally
 * used, rather than C++ -- hence 'functions' instead of 'methods' and
 * 'elements' instead of 'members'.
 *
 * If you are new to RenderWare programming, please read through the
 * supplied User Guide.  The RenderWare Engine \ref rwengine API is
 * usually the starting point for new developers.
 */


#if (!defined(RWFORCEENUMSIZEINT))
#define RWFORCEENUMSIZEINT ((~((RwUInt32)0))>>1)
#endif /* (!defined(RWFORCEENUMSIZEINT)) */

/*
 * See
 * http://www.eskimo.com/~scs/C-faq/q11.17.html
 */

#define RW_STRINGIFY(X) #X
#define RW_STRINGIFY_EXPANDED(X) RW_STRINGIFY(X)

/****************************************************************************
 Attributes
 */

#if (defined(__GNUC__))

/* See http://www.gnu.org/software/gcc/onlinedocs/gcc_4.html#SEC91 */

#if (!(defined(__cplusplus) || defined(__MWERKS__) || defined(__RWUNUSED__)))
#define __RWUNUSED__ __attribute__ ((unused))
#endif /* (!(defined(__cplusplus) || defined(__MWERKS__) || defined(__RWUNUSED__))) */

#if (!(defined(__RWUNUSEDRELEASE__) || defined(RWVALIDATEPARAM)))
#if (!( defined(__cplusplus) || defined(__MWERKS__) || defined(RWDEBUG)))
#define __RWUNUSEDRELEASE__ __attribute__ ((unused))
#endif /* (!(defined(__cplusplus) || defined(__MWERKS__) || defined(RWDEBUG))) */
#endif /* (!(defined(__RWUNUSEDRELEASE__) || defined(RWVALIDATEPARAM))) */

#if (!defined(__RWFORMAT__))
#define __RWFORMAT__(_archetype, _string_index, _first_to_check)        \
    __attribute__ ((format (_archetype, _string_index, _first_to_check)))
#endif /* (!defined(__RWFORMAT__)) */

#endif /* (defined(__GNUC__)) */

#if (!defined(__RWUNUSED__))
#define __RWUNUSED__           /* No op */
#endif /* (!defined(__RWUNUSED__)) */

#if (!defined(__RWUNUSEDRELEASE__))
#define __RWUNUSEDRELEASE__           /* No op */
#endif /* (!defined(__RWUNUSEDRELEASE__)) */

#if (!defined(__RWFORMAT__))
#define __RWFORMAT__(_archetype, _string_index, _first_to_check)  /* No op */
#endif /* (!defined(__RWFORMAT__)) */

/****************************************************************************
 Calling conventions
 */

#if (defined(WIN32))
#define RWASMCALL   __cdecl
#define RWASMAPI(TYPE) TYPE RWASMCALL
#endif /* (defined(WIN32)) */

#if (!defined(RWASMCALL))
#define RWASMCALL              /* No op */
#endif /* (!defined(RWASMCALL)) */

#if (!defined(RWASMAPI))
#define RWASMAPI(TYPE) TYPE
#endif /* (!defined(RWASMAPI)) */


/* Maximum number of nested contexts */
#define rwMAXPIPECONTEXT 10


/****************************************************************************
 Macro wrappers. These are needed everywhere.
 */

#ifndef MACRO_START
#define MACRO_START do
#endif /* MACRO_START */

#ifndef MACRO_STOP
#define MACRO_STOP while(0)
#endif /* MACRO_STOP */

/****************************************************************************
 Types needed everywhere
 */

#ifdef FALSE
#undef FALSE
#endif
#define FALSE 0

#ifdef TRUE
#undef TRUE
#endif
#define TRUE !FALSE

/****************************************************************************
 MS VC/C++ Specific
 */

#if (defined(_MSC_VER))
#if (_MSC_VER>=1000)


/*
 * Check for correct compiler version
 */
#define RW_MSC_VER 1200

#if (0 && !defined(RW_NO_COMPILER_CHECK))
#if (_MSC_VER != RW_MSC_VER )
# pragma message (__FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) "):" "\n  This compiler is a different version (" RW_STRINGIFY_EXPANDED(_MSC_VER) ")\n  to the compiler used to build the RenderWare product libraries (" RW_STRINGIFY_EXPANDED(RW_MSC_VER) ") \n  To turn off this warning please define RW_NO_COMPILER_CHECK " )
# pragma comment ( user, "comment:" __FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) "):" "\n  This compiler is a different version (" RW_STRINGIFY_EXPANDED(_MSC_VER) ")\n  to the compiler used to build the RenderWare product libraries (" RW_STRINGIFY_EXPANDED(RW_MSC_VER) ") \n  To turn off this warning please define RW_NO_COMPILER_CHECK " )
#endif /* (_MSC_VER != RW_MSC_VER ) */
#endif /* (0 && !defined(RW_NO_COMPILER_CHECK)) */

/*
 * Output some compiler messages and object file comments
 */

#pragma comment ( compiler )

#pragma comment ( user, "comment:" __DATE__" "  __TIME__ " - " __FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) ")")
#pragma comment ( user, "comment:" " _MSC_VER==" RW_STRINGIFY_EXPANDED(_MSC_VER) "; _M_IX86==" RW_STRINGIFY_EXPANDED(_M_IX86))
#if (defined(rwLIBRARYCURRENTVERSION))
#pragma comment ( user, "comment:" "rwLIBRARYCURRENTVERSION:" RW_STRINGIFY_EXPANDED(rwLIBRARYCURRENTVERSION) )
#endif /* (defined(rwLIBRARYCURRENTVERSION)) */

#if (defined(RWDEBUG) && defined(RWVERBOSE))

/* #include <windows.h> */
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))
#define _CRTDBG_MAP_ALLOC
#endif /* defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC)) */
#include <crtdbg.h>

#pragma message (__DATE__" "  __TIME__ " - " __FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) ")" )
#pragma message ("_MSC_VER==" RW_STRINGIFY_EXPANDED(_MSC_VER) "; _M_IX86==" RW_STRINGIFY_EXPANDED(_M_IX86))

#if (defined(rwLIBRARYCURRENTVERSION))
#pragma message ( "rwLIBRARYCURRENTVERSION:" RW_STRINGIFY_EXPANDED(rwLIBRARYCURRENTVERSION) )
#endif /* (defined(rwLIBRARYCURRENTVERSION)) */

#endif /* (defined(RWDEBUG) && defined(RWVERBOSE) ) */

#endif /* (_MSC_VER>=1000) */
#endif /* (defined(_MSC_VER)) */

/*******************/
/* Primitive types */
/*******************/

/* String construction stuff (gets us UNICODE support) */
#ifdef RWUNICODE
#define _RWSTRING(x) L ## x
#else /* RWUNICODE */
#define _RWSTRING(x) x
#endif /* RWUNICODE */
#define RWSTRING(x) _RWSTRING(x)

/* NB volatile keyword required for VC5.0 to ensure a reload - AMB */
typedef union RwSplitBits RwSplitBits;
union RwSplitBits
{
    RwReal nReal;
    volatile RwInt32 nInt;
    volatile RwUInt32 nUInt;
};

typedef struct RwSplitFixed RwSplitFixed;

#ifdef rwBIGENDIAN
struct RwSplitFixed
{
    RwInt16 integral;
    RwUInt16 fractional;
};

#else /* rwBIGENDIAN */
#ifdef rwLITTLEENDIAN
struct RwSplitFixed
{
    RwUInt16 fractional;
    RwInt16 integral;
};

#else /* rwLITTLEENDIAN */
#error "ENDIAN-ness undefined!"
#endif /* rwLITTLEENDIAN */
#endif /* rwBIGENDIAN */

typedef union RwUnionReal RwUnionReal;
union RwUnionReal /* MSB is sign bit in any circumstance */
{
    RwReal real; /* 4 bytes interpreted as RwReal */
    float floating; /* 4 bytes interpreted as float */
    RwFixed fixed; /* 4 bytes interpreted as 16:16 fixed */
    RwSplitFixed splitfixed; /* 4 bytes interpreted as 16:16 fixed */
};

/*****************/

/* Complex types */

/*****************/

/**
 * \ingroup datatypes
 * \typedef RwV2d
 * typedef for struct RwV2d
 */
typedef struct RwV2d RwV2d;
/**
 * \ingroup datatypes
 * \struct RwV2d
 * This type represents points in a 2D space, such as device
 * space, specified by the (x, y) coordinates of the point.
 */
struct RwV2d
{
    RwReal x;   /**< X value*/
    RwReal y;   /**< Y vlaue */
};

/**
 * \ingroup datatypes
 * \typedef RwV3d
 * typedef for struct RwV3d
 */
typedef struct RwV3d RwV3d;
/**
 * \ingroup datatypes
 * \struct RwV3d
 *  This type represents 3D points and vectors specified by
 * the (x, y, z) coordinates of a 3D point or the (x, y, z) components of a
 * 3D vector.
 */
struct RwV3d
{
    RwReal x;   /**< X value */
    RwReal y;   /**< Y value */
    RwReal z;   /**< Z value */
};

#define RWV4DALIGNMENT(_v4d) \
   (! (((rwV4DALIGNMENT)-1) & ((RwUInt32)(_v4d))))

/**
 * \ingroup datatypes
 * \struct RwV4d
 *  This type represents 4D points and vectors specified by
 * the (x, y, z, w) coordinates of a 4D point or the (x, y, z, w) components of a
 * 4D vector.
 */
struct RwV4d
{
    RwReal x;   /**< X value */
    RwReal y;   /**< Y value */
    RwReal z;   /**< Z value */
    RwReal w;   /**< W value */
};

/**
 * \ingroup datatypes
 * \typedef RwV4d
 * typedef for struct RwV4d
 */
typedef struct RwV4d RWALIGN(RwV4d, rwV4DALIGNMENT);


/**
 * \ingroup datatypes
 * \typedef RwRect
 * typedef for struct RwRect
 */
typedef struct RwRect RwRect;
/**
 * \ingroup datatypes
 * \struct RwRect
 * This type represents a 2D device space rectangle specified
 * by the position of the top-left corner (the offset x, y) and its width (w)
 * and height (h).
 */
struct RwRect
{
    RwInt32 x;  /**< X value of the top-left corner */
    RwInt32 y;  /**< Y value of the top-left corner */
    RwInt32 w;  /**< Width of the rectangle */
    RwInt32 h;  /**< Height of the rectangle */
};

/**
 * \ingroup datatypes
 * \typedef RwSphere
 * typedef for struct RwSphere
 */
typedef struct RwSphere RwSphere;
/**
 * \ingroup datatypes
 * \struct RwSphere
 * This type represents a sphere specified by the position
 * of its center and its radius
 */
struct RwSphere
{
    RwV3d center;   /**< Sphere center */
    RwReal radius;  /**< Sphere radius */
};

#if (!defined(RwSphereAssign))
#define RwSphereAssign(_target, _source)             \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwSphereAssign)) */

/**
 * \ingroup datatypes
 * \typedef RwLine
 * typedef for struct RwLine
 */
typedef struct RwLine RwLine;
/**
 * \ingroup datatypes
 * \struct RwLine
 * This type represents a 3D line specified by the position
 * of its start and end points.
 */
struct RwLine
{
    RwV3d start;    /**< Line start */
    RwV3d end;      /**< Line end */
};

#if (!defined(RwLineAssign))
#define RwLineAssign(_target, _source)             \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwLineAssign)) */

/* The maximum number of texture coordinates */
#if (rwLIBRARYCURRENTVERSION > 0x310)
/* MULTITEXTURE */
#define rwMAXTEXTURECOORDS 8
#else
#define rwMAXTEXTURECOORDS 2
#endif

/**
 * \ingroup datatypes
 * RwTextureCoordinateIndex
 *  This type represents the index for texture coordinates.
 */
enum RwTextureCoordinateIndex
{
    rwNARWTEXTURECOORDINATEINDEX = 0,
    rwTEXTURECOORDINATEINDEX0,
    rwTEXTURECOORDINATEINDEX1,
    rwTEXTURECOORDINATEINDEX2,
    rwTEXTURECOORDINATEINDEX3,
    rwTEXTURECOORDINATEINDEX4,
    rwTEXTURECOORDINATEINDEX5,
    rwTEXTURECOORDINATEINDEX6,
    rwTEXTURECOORDINATEINDEX7,
    rwTEXTURECOORDINATEINDEXFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwTextureCoordinateIndex RwTextureCoordinateIndex;

/**
 * \ingroup datatypes
 * \typedef RwTexCoords
 * typedef for struct RwTexCoords
 */
typedef struct RwTexCoords RwTexCoords;
/**
 * \ingroup datatypes
 * \struct RwTexCoords
 * This type represents the the u and v texture
 * coordinates of a particular vertex.
 */
struct RwTexCoords
{
    RwReal u;   /**< U value */
    RwReal v;   /**< V value */
};


/* Singley linked list macros. End marked as NULL */

typedef struct RwSLLink RwSLLink;    /*** RwSLLink ***/
struct RwSLLink
{
    RwSLLink  *next;
};

#define rwSLLinkGetData(link,type,entry)                                \
    ((type *)(((RwUInt8 *)(link))-offsetof(type,entry)))
#define rwSLLinkInitialize(linkvar)                                     \
    (linkvar)->next = NULL;
#define rwSLLinkGetNext(linkvar)                                        \
    ((linkvar)->next)

typedef struct RwSingleList RwSingleList;
struct RwSingleList
{
    RwSLLink link;
};

#define rwSingleListInitialize(list)                                    \
    (list)->link.next= NULL;
#define rwSingleListEmpty(list)                                         \
    (((list)->link.next)==NULL)
#define rwSingleListAddSLLink(list,linkvar)                             \
    MACRO_START                                                         \
    {                                                                   \
        (linkvar)->next = (list)->link.next;                            \
        (list)->link.next = (linkvar);                                  \
    }                                                                   \
    MACRO_STOP
#define rwSingleListGetFirstSLLink(list)                                \
    ((list)->link.next)
#define rwSingleListGetTerminator(list) (NULL)

/* Doubly linked list. End marked as start (its a ring) */

typedef struct RwLLLink  RwLLLink;                     /*** RwLLLink ***/
struct RwLLLink
{
    RwLLLink *next;
    RwLLLink *prev;
};

#define rwLLLinkGetData(linkvar,type,entry)                             \
    ((type *)(((RwUInt8 *)(linkvar))-offsetof(type,entry)))
#define rwLLLinkGetNext(linkvar)                                        \
    ((linkvar)->next)
#define rwLLLinkGetPrevious(linkvar)                                    \
    ((linkvar)->prev)
#define rwLLLinkInitialize(linkvar)                                     \
    MACRO_START                                                         \
    {                                                                   \
        (linkvar)->prev = (RwLLLink *)NULL;                             \
        (linkvar)->next = (RwLLLink *)NULL;                             \
    }                                                                   \
    MACRO_STOP
#define rwLLLinkAttached(linkvar)                                       \
    ((linkvar)->next)

typedef struct RwLinkList RwLinkList;
struct RwLinkList
{
    RwLLLink link;
};

#define rwLinkListInitialize(list)                                      \
    MACRO_START                                                         \
    {                                                                   \
        (list)->link.next = ((RwLLLink *)(list));                       \
        (list)->link.prev = ((RwLLLink *)(list));                       \
    }                                                                   \
    MACRO_STOP
#define rwLinkListEmpty(list)                                           \
    (((list)->link.next) == (&(list)->link))
#define rwLinkListAddLLLink(list, linkvar)                              \
    MACRO_START                                                         \
    {                                                                   \
        (linkvar)->next = (list)->link.next;                            \
        (linkvar)->prev = (&(list)->link);                              \
        ((list)->link.next)->prev = (linkvar);                          \
        (list)->link.next = (linkvar);                                  \
    }                                                                   \
    MACRO_STOP
#define rwLinkListRemoveLLLink(linkvar)                                 \
    MACRO_START                                                         \
    {                                                                   \
        ((linkvar)->prev)->next = (linkvar)->next;                      \
        ((linkvar)->next)->prev = (linkvar)->prev;                      \
    }                                                                   \
    MACRO_STOP
#define rwLinkListGetFirstLLLink(list)                                  \
    ((list)->link.next)
#define rwLinkListGetLastLLLink(list)                                   \
    ((list)->link.prev)
#define rwLinkListGetTerminator(list)                                   \
    (&((list)->link))

/**
 * \ingroup datatypes
 * \typedef RwSurfaceProperties
 * typedef for struct RwSurfaceProperties
 */
typedef struct RwSurfaceProperties RwSurfaceProperties;
/**
 * \ingroup datatypes
 * \struct RwSurfaceProperties
 *  This type represents the ambient, diffuse and
 * specular reflection coefficients of a particular geometry. Each coefficient
 * is specified in the range 0.0 (no reflection) to 1.0 (maximum reflection).
 */
struct RwSurfaceProperties
{
    RwReal ambient;   /**< ambient reflection coefficient */
    RwReal specular;  /**< specular reflection coefficient */
    RwReal diffuse;   /**< reflection coefficient */
};

#if (!defined(RwSurfacePropertiesAssign))
#define RwSurfacePropertiesAssign(_target, _source)             \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwSurfacePropertiesAssign)) */

/**********
 * Macros *
 **********/

/* ANSI C defines the offsetof(type,member) macro; should be in <stddef.h> */

/* If not, fall back to this: */
#ifndef offsetof
#define offsetof(type, member)                                          \
    ((size_t)((RwUInt8 *)&((type *) 0)->member - (RwUInt8 *)((type *) 0)))
#endif /* offsetof */

/*
 *
 * Numeric Macros to handle Fixed/Floating point versions of RenderWare
 *
 */
#define RWFIX_MIN     (1)
#define RWFIX_MAX     (0x7fffffff)
#define RwFixedCast(A)     ((RwFixed)((A) * 65536.0f))
#define RwFixedToInt(A)    ((A) >> 16)
#define RwFixedToFloat(A)  ((float)(((float)(A)) * (1.0f / 65536.0f)))
#define RwFixedToReal(a)    ((RwReal)(((RwReal)(a)) * (1.0f / 65536.0f)))
#define RwRealToFixed(a)    ((RwFixed)((a) * 65536.0f))
#define RwRealAbs(a)       ((RwReal)((a) >= (RwReal)(0.0) ? (a) : (-(a))))
#define RwRealMin2(a,b)    ((RwReal)( ((a) <= (b)) ?  (a) : (b)))
#define RwRealMax2(a,b)    ((RwReal)( ((a) >= (b)) ?  (a) : (b)))
#define RwRealMin3(a,b,c)  RwRealMin2(a,RwRealMin2(b,c))
#define RwRealMax3(a,b,c)  RwRealMax2(a,RwRealMax2(b,c))

#ifndef NORWREALSHORTCUT
#define RToFixed RwRealToFixed
#define RAbs     RwRealAbs
#define FxCast    RwFixedCast
#define FxToInt   RwFixedToInt
#define FxToFloat RwFixedToFloat
#define FxToReal  RwFixedToFloat

#endif

#ifndef rwPI
#define rwPI ((RwReal)(3.1415926535f))
#define rwPIOVER2 (rwPI / (RwReal)(2.0f))
#endif
#define RWRGBALONG(r,g,b,a)                                             \
    ((RwUInt32) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)))

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                             RwPlane

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */


/*
 * typedef for struct RwPlane
 */
typedef struct RwPlane RwPlane;
/*
 * This type represents a plane
 */
struct RwPlane
{
    RwV3d normal;    /**< Normal to the plane */
    RwReal distance; /**< Distance to plane from origin in normal direction*/
};


/****************************************************************************
 Defines
 */

enum RwPlaneType
{
    rwXPLANE = 0, /* These are deliberately multiples of sizeof(RwReal) */
    rwYPLANE = 4,
    rwZPLANE = 8,
    rwPLANETYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwPlaneType RwPlaneType;

#define rwSECTORATOMIC -1
#define rwSECTORBUILD -2       /* Only used when building a world */

/* vect is a RwV3d, y is the component */
#define GETCOORD(vect,y)                                                \
    (*(RwReal *)(((RwUInt8 *)(&((vect).x)))+(RwInt32)(y)))
#define GETCONSTCOORD(vect,y)                                           \
    (*(const RwReal *)(((const RwUInt8 *)(&((vect).x)))+(RwInt32)(y)))
#define SETCOORD(vect,y,value)                                          \
    (((*(RwReal *)(((RwUInt8 *)(&((vect).x)))+(RwInt32)(y))))=(value))
#define SETCONTCOORD(vect,y,value)                                      \
    (((*(const RwReal *)                                                \
       (((const RwUInt8 *)                                              \
         (&((vect).x)))+(RwInt32)(y))))=(value))
#define GETCOORDINT(vect,y)                                             \
    (*(RwInt32 *)(((RwUInt8 *)(&((vect).x)))+(y)))
#define GETCONSTCOORDINT(vect,y)                                        \
    (*(const RwInt32 *)(((const RwUInt8 *)(&((vect).x)))+(y)))


/**
 * \ingroup rwcore
 * \page inttypes Integer Types
 *
 * RenderWare supports a number of integer types:
 *
 * RwInt8 8-bit signed integer.
 *    \li RwUInt8 8-bit unsigned integer.
 *    \li RwChar Character type.
 *    \li RwInt16 16-bit signed integer.
 *    \li RwUInt16 16-bit unsigned integer.
 *    \li RwInt32 32-bit signed integer.
 *    \li RwUInt32 32-bit unsigned integer.
 *    \li RwInt64 64-bit signed integer.
 *    \li RwUInt64 64-bit unsigned integer.
 *    \li RwInt128 128-bit signed integer.
 *    \li RwUInt128 128-bit unsigned integer.
 *    \li RwBool Boolean type (in 32 bits).
 *
 * These types should be used in applications in preference to the underlying
 * native types. 
 * 
 * The following constants indicate the maximum and minimum values possible
 * for the various RenderWare integer types:
 *
 *    \li RwInt32MAXVAL   Maximum RwInt32 value.
 *    \li RwInt32MINVAL   Minimum RwInt32 value.
 *    \li RwUInt32MAXVAL   Maximum RwUInt32 value.
 *    \li RwUInt32MINVAL   Minimum RwUInt32 value.
 *    \li RwInt16MAXVAL   Maximum RwInt16 value.
 *    \li RwInt16MINVAL   Minimum RwInt16 value.
 *    \li RwUInt16MAXVAL   Maximum RwUInt16 value.
 *    \li RwUInt16MINVAL   Minimum RwUInt16 value.
 *
 * \see RwReal
 */

/**
 * \ingroup datatypes
 * \typedef RwReal 
 *
 * RenderWare supports a single RwReal floating-point type to aid portability
 * across platforms. This type should be used in applications in preference to
 * the underlying native type.
 *
 * The constants RwRealMAXVAL and RwRealMINVAL are provided for determining
 * the maximum and minimum values possible using the RwReal type.
 *
 * In addition, the following macros are available for operations on RwReal
 * types:
 *      \li RwRealMin2(a, b)    Find the minimum of two RwReal values.
 *      \li RwRealMax2(a, b)    Find the maximum of two RwReal values.
 *      \li RwRealMin3(a, b, c)    Find the minimum of three RwReal values.
 *      \li RwRealMax3(a, b, c)    Find the maximum of three RwReal values.
 *      \li RwRealAbs(x)    Find the absolute value of a RwReal value.
 *
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwFixed
 * 
 * RenderWare Graphics supports a single RwFixed fixed-point type.
 *
 * Although popular in the days when integer math was much faster than floating point math, 
 * fixed-point math is now rarely used. It is provided because it is still useful for some
 * processes.
 *
 * The maximum and minimum size of an RwFixed value are defined by the constants
 * RWFIX_MAX and RWFIX_MIN respectively.
 *
 * The following macros are provided to help you work with RwFixed datatypes:
 *    \li RwFixedCast(x)        Cast the integer portion of an RwFixed to another type.
 *    \li RwFixedToInt(x)       Convert an RwFixed to an integer. (The fractional portion is lost.)
 *    \li RwFixedToFloat(x)     Convert an RwFixed to a float.
 *    \li RwFixedToReal(x)      Convert an RwFixed to an RwReal.
 *    \li RwRealToFixed(x)      Convert an RwReal to an RwFixed. (Some precision may be lost.)
 */

/** 
 * \ingroup datatypes
 * \typedef RwInt8    
 * 
 * Signed 8 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwUInt8   
 *
 * Unsigned 8bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwChar    
 *
 * Character type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwInt16   
 *
 * Signed 16 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwUInt16  
 *
 * Unsigned 16 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwInt32   
 *
 * Signed 32 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwUInt32  
 *
 * Unsigned 32 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwInt64   
 *
 * Signed 64 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwUInt64  
 *
 * Unsigned 64 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwInt128  
 *
 * Signed 128 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwUInt128 
 *
 * Unsigned 128 bit integer type.
 * \see \ref inttypes
 */

/** 
 * \ingroup datatypes
 * \typedef RwBool    
 *
 * Boolean type.
 * \see \ref inttypes
 */
 

/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/dmaalloc.h ---*/
/* Allocation flags - when the types change, alignment to a cache line occurs
 * to prevent DMA/DCACHE interaction.
 */
#define calDMA_ALLOC 1
#define calDCACHE_ALLOC 2


/**
 * $ingroup driversky2
 * $typedef RwSkySplitBits128
 */
typedef union RwSkySplitBits128 RwSkySplitBits128;

/**
 * \ingroup driversky2
 * \union RwSkySplitBits128
 * Union for accessing fields of packed 128 bit quadword
 */
union RwSkySplitBits128
{
    u_long128           field128;     /**< Packed 128 bit quadword  */
    RwUInt64            field_64[2];  /**< Composite bi-word fields */
    RwSplitBits         field_32[4];  /**< Composite quad-word fields */
};

typedef struct circularAllocatorBlock circularAllocatorBlock;
struct circularAllocatorBlock
{
    circularAllocatorBlock *next;                       /**< Internal use */
    RwUInt32 waterLevel;                                /**< Internal use */
    RwUInt32 numBlocksAlloced;                          /**< Internal use */
    void *memory;                                       /**< Internal use */
    void *realMemory;                                   /**< Internal use */
};

typedef struct circularAllocator circularAllocator;
struct circularAllocator
{
    RwUInt32 blockSize;                                 /**< Internal use */

    circularAllocatorBlock *firstBlock;                 /**< Internal use */
    circularAllocatorBlock *activeAllocBlock;           /**< Internal use */
    circularAllocatorBlock *activeFreeBlock;            /**< Internal use */

    void *lastBlockAllocated;                           /**< Internal use */
    RwUInt32 lastBlockSize;                             /**< Internal use */
    RwUInt32 lastBlockFlags;                            /**< Internal use */
    RwUInt32 showNewBlocks;                             /**< Internal use */
    RwUInt32 limit;                                     /**< Internal use */
};

/* Max size of block the circular allocator will allocate */
extern RwUInt32 sweCircAllocBlockSize;

extern void *
circularMalloc(circularAllocator *allocator,
               RwUInt32 size,
               RwUInt32 flags);

extern void *
circularRealloc(circularAllocator *allocator,
                void *memory,
                RwUInt32 size);

extern void 
circularFree(circularAllocator *allocator,
             void *memory);

extern circularAllocator *
circularAllocOpen(RwUInt32 blockSize);

extern RwBool 
circularAllocClose(circularAllocator *allocator);

extern RwBool 
circularAllocPreAlloc(circularAllocator *allocator, 
                      int size);

extern RwBool 
circularLimitAlloc(circularAllocator *allocator, 
                   RwBool limit);
#if (!defined(RXPIPELINE))
#define RXPIPELINE
#endif /* (!defined(RXPIPELINE)) */

/*--- Automatically derived from: E:/nightly/rwsdk/src/batype.h ---*/
/****************************************************************************
 Defines
*/

/* 
 * Object Types - these are used in the binary object 
 * representations and in the debug library. They must 
 * be unique.  They are the old system.
 */

#define rwID_DATABASE 0x64617462     /* datb */

#define MAKECHUNKID(vendorID, chunkID) (((vendorID & 0xFFFFFF) << 8) | (chunkID & 0xFF))
#define GETOBJECTID(chunkID) (chunkID & 0xFF)
#define GETVENDORID(chunkID) ((chunkID >> 8) & 0xFFFFFF)

/***
 *** These are the vendor IDs.  A customer must reserve a vendor ID in order
 *** to be able to write toolkits (this prevents clashes between toolkits).
 *** We reserve some for our own use as shown below.  These are all 24 bit.
 ***
 *** IMPORTANT NOTE: DO NOT UNDER ANY CIRCUMSTANCES CHANGE THESE VALUES. IF
 ***                 YOU ARE ADDING A NEW ONE, APPEND IT!
 ***
 *** They must all be unique.
 ***/

enum RwPluginVendor
{
    rwVENDORID_CORE             = 0x000000L,
    rwVENDORID_CRITERIONTK      = 0x000001L,
    rwVENDORID_REDLINERACER     = 0x000002L,
    rwVENDORID_CSLRD            = 0x000003L,
    rwVENDORID_CRITERIONINT     = 0x000004L,
    rwVENDORID_CRITERIONWORLD   = 0x000005L,
    rwVENDORID_BETA             = 0x000006L,
    rwVENDORID_CRITERIONRM      = 0x000007L,
    rwVENDORID_CRITERIONRWA     = 0x000008L, /* RenderWare Audio */
    rwPLUGINVENDORFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwPluginVendor RwPluginVendor;

/***
 *** These are the core objects (8 bit IDs).  They must all be unique.
 *** We can get away without using the MAKECHUNKID macro because the
 *** vendor ID in all cases will be zero (rwVENDORID_CORE).
 ***
 *** IMPORTANT NOTE: DO NOT UNDER ANY CIRCUMSTANCES CHANGE THESE VALUES. IF
 ***                 YOU ARE ADDING A NEW ONE, APPEND IT!
 ***/

/* These are the internal ones.  Because the core ID is 0, we can get away without
 * using the MAKECHUNKID macro for the CORE chunks.
 */

enum RwCorePluginID
{
    rwID_NAOBJECT               = 0x00,
    rwID_STRUCT                 = 0x01,
    rwID_STRING                 = 0x02,
    rwID_EXTENSION              = 0x03,
    rwID_CAMERA                 = 0x05,
    rwID_TEXTURE                = 0x06,
    rwID_MATERIAL               = 0x07,
    rwID_MATLIST                = 0x08,
    rwID_ATOMICSECT             = 0x09,
    rwID_PLANESECT              = 0x0A,
    rwID_WORLD                  = 0x0B,
    rwID_SPLINE                 = 0x0C,
    rwID_MATRIX                 = 0x0D,
    rwID_FRAMELIST              = 0x0E,
    rwID_GEOMETRY               = 0x0F,
    rwID_CLUMP                  = 0x10,
    rwID_LIGHT                  = 0x12,
    rwID_UNICODESTRING          = 0x13,
    rwID_ATOMIC                 = 0x14,
    rwID_TEXTURENATIVE          = 0x15,
    rwID_TEXDICTIONARY          = 0x16,
    rwID_ANIMDATABASE           = 0x17,
    rwID_IMAGE                  = 0x18,
    rwID_SKINANIMATION          = 0x19,
    rwID_GEOMETRYLIST           = 0x1A,
    rwID_HANIMANIMATION         = 0x1B,
    rwID_TEAM                   = 0x1C,
    rwID_CROWD                  = 0x1D,
    rwID_DMORPHANIMATION        = 0x1E,
    rwCOREPLUGINIDFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwCorePluginID RwCorePluginID ;

/***
 *** These are the Criterion internal plugin extensions.  Use with rwVENDORID_CRITERIONINT.
 ***
 *** IMPORTANT NOTE: DO NOT UNDER ANY CIRCUMSTANCES CHANGE THESE VALUES. IF
 ***                 YOU ARE ADDING A NEW ONE, APPEND IT!
 ***/

enum RwCriterionPluginID 
{
    rwID_COREPLUGIN             = 0x01,
    rwID_WORLDPLUGIN            = 0x02,
    rwID_TOOLPLUGIN             = 0x03,
    rwID_TOOL2PLUGIN            = 0x04,
    rwCRITERIONPLUGINIDFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwCriterionPluginID RwCriterionPluginID;


/***
 *** These are the Criterion internal platform identifies.
 ***
 *** IMPORTANT NOTE: DO NOT UNDER ANY CIRCUMSTANCES CHANGE THESE VALUES. IF
 ***                 YOU ARE ADDING A NEW ONE, APPEND IT!
 ***/
enum RwPlatformID
{
    rwID_PCDX7 = 1,
    rwID_PCOGL,
    rwID_MAC,
    rwID_PS2,
    rwID_XBOX,
    rwID_GAMECUBE,
    rwID_SOFTRAS,
    rwID_PCDX8,
    rwPLATFROMIDFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwPlatformID RwPlatformID;


/****************************************************************************
 Global Types
 */

typedef struct RwObject RwObject;
/**
 * \ingroup datatypes
 * \struct RwObject 
 * This should be considered an opaque type. Use
 * the RwObject API functions to access.
 */
struct RwObject
{
        RwUInt8 type;                /**< Internal Use */
        RwUInt8 subType;             /**< Internal Use */
        RwUInt8 flags;               /**< Internal Use */
        RwUInt8 privateFlags;        /**< Internal Use */
        void   *parent;              /**< Internal Use */
                                     /* Often a Frame  */
};

/**
 * \ingroup datatypes
 * \typedef RwObjectCallBack
 * callback function supplied for object callback functions.
 *
 * \return Pointer to the current object
 * 
 * \param  object   Pointer to the current object, supplied by
 * iterator.
 * \param  data  Pointer to developer-defined data structure.
 *
 * \see RwFrameForAllObjects
 *
 */
typedef RwObject *(*RwObjectCallBack)(RwObject *object, void *data);

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* TYPE METHODS */

/* Creation/cloning */

#define rwObjectCopy(d,s)                               \
MACRO_START                                             \
{                                                       \
    ((RwObject *)(d))->type =                           \
        ((const RwObject *)(s))->type;                  \
    ((RwObject *)(d))->subType =                        \
        ((const RwObject *)(s))->subType;               \
    ((RwObject *)(d))->flags =                          \
        ((const RwObject *)(s))->flags;                 \
    ((RwObject *)(d))->privateFlags =                   \
        ((const RwObject *)(s))->privateFlags;          \
    ((RwObject *)(d))->parent =                         \
        NULL;                                           \
}                                                       \
MACRO_STOP

#define rwObjectInitialize(o, t, s)                     \
MACRO_START                                             \
{                                                       \
    ((RwObject *)(o))->type = (RwUInt8)(t);             \
    ((RwObject *)(o))->subType = (RwUInt8)(s);          \
    ((RwObject *)(o))->flags = 0;                       \
    ((RwObject *)(o))->privateFlags = 0;                \
    ((RwObject *)(o))->parent = NULL;                   \
}                                                       \
MACRO_STOP

/* Debug */
#define RwObjectGetType(o)                  (((const RwObject *)(o))->type)

#define rwObjectSetType(o, t)               (((RwObject *)(o))->type) = (RwUInt8)(t)

/* Sub type */
#define rwObjectGetSubType(o)               (((const RwObject *)(o))->subType)
#define rwObjectSetSubType(o, t)            (((RwObject *)(o))->subType) = (RwUInt8)(t)

/* Flags */
#define rwObjectGetFlags(o)                 (((const RwObject *)(o))->flags)
#define rwObjectSetFlags(o, f)              (((RwObject *)(o))->flags) = (RwUInt8)(f)
#define rwObjectTestFlags(o, f)             ((((const RwObject *)(o))->flags) & (RwUInt8)(f))

/* Private flags */
#define rwObjectGetPrivateFlags(c)          (((const RwObject *)(c))->privateFlags)
#define rwObjectSetPrivateFlags(c,f)        (((RwObject *)(c))->privateFlags) = (RwUInt8)(f)
#define rwObjectTestPrivateFlags(c,flag)    ((((const RwObject *)(c))->privateFlags) & (RwUInt8)(flag))

/* Hierarchy */
#define rwObjectGetParent(object)           (((const RwObject *)(object))->parent)
#define rwObjectSetParent(c,p)              (((RwObject *)(c))->parent) = (void *)(p)

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2resort.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2macros.h ---*/

#define RxClusterDecCursorByStride(_cluster, _stride)                           \
    ((_cluster)->currentData =                                                  \
      (void *)(((RwUInt8 *)(_cluster)->currentData) -                           \
         (_stride)))

#define RxClusterDecCursor(_cluster) \
    RxClusterDecCursorByStride(_cluster, (_cluster)->stride)

#define RxClusterIncCursorByStride(_cluster, _stride)                           \
    ((_cluster)->currentData =                                                  \
     (void *)(((RwUInt8 *)(_cluster)->currentData) +                            \
              (_stride)))

#define RxClusterIncCursor(_cluster) \
    RxClusterIncCursorByStride(_cluster, (_cluster)->stride)

#define RxClusterResetCursor(_cluster) \
    ((_cluster)->currentData = (_cluster)->data)

#define RxClusterGetCursorData(_cluster, _type) \
    ((_type *)(_cluster)->currentData)

#define RxClusterGetIndexedData(_cluster, _type, _index)                        \
    ((_type *)(((RwUInt8 *)(_cluster)->data) + (_cluster)->stride*(_index)))

#define RxClusterGetFreeIndex(_cluster) ( (_cluster)->numUsed++ )

#define RxPipelineClusterAssertAttributeSet(_cluster, _attributeSet)    \
    RWASSERT( (_cluster)->clusterRef->attributeSet != NULL &&           \
              strcmp((_cluster)->clusterRef->attributeSet,              \
                     (_attributeSet)) == 0 )

#define RxPipelineNodeParamGetData(_param) \
    ( (_param)->dataParam )

#define RxPipelineNodeParamGetHeap(_param) \
    ( (_param)->heap )



/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2heap.h ---*/

#if (defined(RWDEBUG) && (defined(RWMEMDEBUG)))

#if (!defined(DISABLERWHEAP))
#define DISABLERWHEAP
#endif /* (!defined(DISABLERWHEAP)) */

#endif /* (defined(RWDEBUG) && (defined(RWMEMDEBUG))) */

typedef struct rxHeapFreeBlock rxHeapFreeBlock;
typedef struct rxHeapSuperBlockDescriptor rxHeapSuperBlockDescriptor;
typedef struct RxHeap RxHeap;
typedef struct rxHeapBlockHeader rxHeapBlockHeader;

struct rxHeapFreeBlock
{
    RwUInt32            size;
    rxHeapBlockHeader  *ptr;
};

struct rxHeapSuperBlockDescriptor
{
    void *start;
    RwUInt32 size;
    rxHeapSuperBlockDescriptor *next;
};

/**
 * \ingroup rwcoregeneric
 * \struct RxHeap 
 * structure describing a pipeline execution heap 
 */
struct RxHeap
{
    RwUInt32            superBlockSize; /**< Granularity of heap growth */
    rxHeapSuperBlockDescriptor *head;   /**< Internally used superblock pointer */
    rxHeapBlockHeader  *headBlock;      /**< Internally used block pointer */
    rxHeapFreeBlock    *freeBlocks;     /**< Internally used free blocks pointer */
    RwUInt32            entriesAlloced; /**< Number of entries allocated */
    RwUInt32            entriesUsed;    /**< Number of entries used */
};

struct rxHeapBlockHeader
{
    /* present in all blocks (used & unused) */
    rxHeapBlockHeader  *prev, *next;
    RwUInt32            size;
    rxHeapFreeBlock    *freeEntry; /* (or null) */
    RwUInt32            pad[4]; /* alignment padding to 32 bytes */
};

#ifdef __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

extern RxHeap      *RxHeapCreate(RwUInt32 size);
extern void         RxHeapDestroy(RxHeap * heap);
extern RwBool       RxHeapReset(RxHeap * heap);
extern void        *RxHeapAlloc(RxHeap * heap, RwUInt32 size);
extern void         RxHeapFree(RxHeap * heap, void *block);
extern void        *RxHeapRealloc(RxHeap * heap, void *block,
                                  RwUInt32 newSize, RwBool allowCopy);

#ifdef __cplusplus
}
#endif                          /* __cplusplus */

#if (defined(DISABLERWHEAP))

typedef struct rxHeapMallocTrace rxHeapMallocTrace;
struct rxHeapMallocTrace
{
    rxHeapMallocTrace *next;
    rxHeapBlockHeader *block;
};

#endif                          /* (defined(DISABLERWHEAP)) */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2dep.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/rwstring.h ---*/

/****************************************************************************
 Defines
 */

#define rwsprintf   RWSRCGLOBAL(stringFuncs).vecSprintf
#define rwvsprintf  RWSRCGLOBAL(stringFuncs).vecVsprintf
#define rwstrcpy    RWSRCGLOBAL(stringFuncs).vecStrcpy
#define rwstrncpy   RWSRCGLOBAL(stringFuncs).vecStrncpy
#define rwstrcat    RWSRCGLOBAL(stringFuncs).vecStrcat
#define rwstrncat   RWSRCGLOBAL(stringFuncs).vecStrncat
#define rwstrrchr   RWSRCGLOBAL(stringFuncs).vecStrrchr
#define rwstrchr    RWSRCGLOBAL(stringFuncs).vecStrchr
#define rwstrstr    RWSRCGLOBAL(stringFuncs).vecStrstr
#define rwstrcmp    RWSRCGLOBAL(stringFuncs).vecStrcmp
#define rwstricmp   RWSRCGLOBAL(stringFuncs).vecStricmp
#define rwstrlen    RWSRCGLOBAL(stringFuncs).vecStrlen
#define rwstrupr    RWSRCGLOBAL(stringFuncs).vecStrupr
#define rwstrlwr    RWSRCGLOBAL(stringFuncs).vecStrlwr
#define rwstrtok    RWSRCGLOBAL(stringFuncs).vecStrtok
#define rwsscanf    RWSRCGLOBAL(stringFuncs).vecSscanf

#define rwstrdup(_result, _string)                \
do                                                \
{                                                 \
    _result = ((RwChar*)NULL);                    \
                                                  \
    if (((RwChar*)NULL) != (_string))             \
    {                                             \
        _result = (RwChar *)                      \
            RwMalloc( (rwstrlen(_string) + 1) *   \
                      sizeof (RwChar) );          \
                                                  \
        if (((RwChar*)NULL) != (_result))         \
        {                                         \
            rwstrcpy(_result, _string);           \
        }                                         \
    }                                             \
}                                                 \
while (0)


/****************************************************************************
 Global Types
 */

typedef int (*vecSprintfFunc)(RwChar *buffer,
                              const RwChar *format,
                              ...) /* __RWFORMAT__(printf, 2, 3) */; 
typedef int (*vecVsprintfFunc)(RwChar *buffer,
                               const RwChar *format,
                               va_list argptr); 
typedef RwChar *(*vecStrcpyFunc)(RwChar *dest,
                                 const RwChar *srce);
typedef RwChar *(*vecStrncpyFunc)(RwChar *dest,
                                  const RwChar *srce,
                                  size_t size);
typedef RwChar *(*vecStrcatFunc)(RwChar *dest,
                                 const RwChar *srce);
typedef RwChar *(*vecStrncatFunc)(RwChar *dest,
                                  const RwChar *srce,
                                  size_t size);
typedef RwChar *(*vecStrrchrFunc)(const RwChar *string,
                                  int findThis);
typedef RwChar *(*vecStrchrFunc)(const RwChar *string,
                                 int findThis);
typedef RwChar *(*vecStrstrFunc)(const RwChar *string,
                                 const RwChar *findThis);
typedef int (*vecStrcmpFunc)(const RwChar *string1,
                             const RwChar *string2);
typedef int (*vecStricmpFunc)(const RwChar *string1,
                              const RwChar *string2);
typedef size_t (*vecStrlenFunc)(const RwChar *string);
typedef RwChar *(*vecStruprFunc)(RwChar *string);
typedef RwChar *(*vecStrlwrFunc)(RwChar *string);
typedef RwChar *(*vecStrtokFunc)(RwChar *string, const RwChar *delimit);
typedef int (*vecSscanfFunc)(const RwChar *buffer,
                             const RwChar *format,
                             ...) /* __RWFORMAT__(scanf, 2, 3) */;

typedef struct RwStringFunctions RwStringFunctions;
struct RwStringFunctions
{
    vecSprintfFunc vecSprintf ;
    vecVsprintfFunc vecVsprintf;
    vecStrcpyFunc vecStrcpy;
    vecStrncpyFunc vecStrncpy;
    vecStrcatFunc vecStrcat;
    vecStrncatFunc vecStrncat;
    vecStrrchrFunc vecStrrchr;
    vecStrchrFunc vecStrchr;
    vecStrstrFunc vecStrstr;
    vecStrcmpFunc vecStrcmp;
    vecStricmpFunc vecStricmp;
    vecStrlenFunc vecStrlen;
    vecStruprFunc vecStrupr;
    vecStrlwrFunc vecStrlwr;
    vecStrtokFunc vecStrtok;
    vecSscanfFunc vecSscanf;
};


/*--- Automatically derived from: E:/nightly/rwsdk/src/rwdbgerr.h ---*/
#define RWECODE(a,b) a,

/* Construct an enum type with all the plugin error codes (for the app to use) */
enum RwErrorCodePlugin_errcore 
{
#include "errcore.def"
    rwLASTERROR_errcore = RWFORCEENUMSIZEINT
};
typedef enum RwErrorCodePlugin_errcore RwErrorCodePlugin_errcore;


#undef RWECODE


/*--- Automatically derived from: E:/nightly/rwsdk/src/resmem.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/baresour.h ---*/
/****************************************************************************
 Global Types
 */

/**
 * \ingroup datatypes
 * \typedef RwResEntry 
 * RwResEntry object. Instanced data block in resources arena.  
 * This should be considered an opaque
 * type. Use the RwResEntry API functions to access.
 */
typedef struct RwResEntry RwResEntry;

/**
 * \ingroup datatypes
 * \typedef RwResEntryDestroyNotify
 * This type represents the function
 * called from \ref RwResourcesFreeResEntry (and indirectly from 
 * \ref RwResourcesEmptyArena) immediately before the memory used by the
 * specified resources entry is released.
 *
 * \param  entry   Pointer to the instanced data. 
 */
typedef void        (*RwResEntryDestroyNotify) (RwResEntry * resEntry);

#if (!defined(DOXYGEN))
struct RwResEntry
{
    RwLLLink            link;   /**< Node in the list of resource elements */
    RwInt32             size;   /**< Size of this node */
    void               *owner;  /**< Owner of this node */
    RwResEntry        **ownerRef; /**< Pointer to pointer to this (enables de-alloc) */
    RwResEntryDestroyNotify destroyNotify; /**< This is called right before destruction */
};
#endif /* (!defined(DOXYGEN)) */

enum rwResEntryMemoryPool
{
    rwMEMORYPOOLDEFAULT = 0,
    rwMEMORYPOOLARENA,
    rwMEMORYFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum rwResEntryMemoryPool rwResEntryMemoryPool;

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

/* Setting the resources arena size */
extern RwBool       RwResourcesSetArenaSize(RwInt32 size);
extern RwInt32      RwResourcesGetArenaSize(void);
extern RwInt32      RwResourcesGetArenaUsage(void);
extern RwBool       RwResourcesEmptyArena(void);

/* Allocation */

/**
 * \ingroup rwresources
 * \def RwResourcesAllocateResEntry is a macro used to allocate 
 * a resources entry for the specified object of the given size. 
 * Also use this function to 
 * specify a callback function that will be executed immediately before the
 * resources entry is removed from the resources arena (pass NULL to indicate 
 * there is no callback).
 * 
 * \param owner  Pointer to the object that will own the resources entry.
 * \param ownerRef  Pointer to a pointer that will receive a reference to 
 *       the resources entry.
 * \param size  A RwInt32 value equal to the size of the resources entry 
 *       to allocate (in bytes).
 * \param destroyNotify  Pointer to destroy notify callback function. 
 *       Specify NULL to ignore.
 *
 * \return Returns pointer to the allocated resources block if successful
 *        or NULL if there is an error.
 * 
 * \see RwResourcesFreeResEntry
 * \see RwResourcesUseResEntry
 */
#define RwResourcesAllocateResEntry(_owner, _ownerRef, _size, _destroyNotify) \
       _rwResourcesAllocateResEntry(_owner,                                   \
                                    _ownerRef,                                \
                                    _size,                                    \
                                    rwMEMORYPOOLARENA,                        \
                                    _destroyNotify)

extern RwResEntry  *_rwResourcesAllocateResEntry(void *owner,
                                                 RwResEntry **
                                                 ownerRef,
                                                 RwInt32 size,
                                                 rwResEntryMemoryPool
                                                 pool,
                                                 RwResEntryDestroyNotify
                                                 destroyNotify);
/* Deallocation */
extern RwBool       RwResourcesFreeResEntry(RwResEntry * entry);
/* Mark all as unused */
extern void         _rwResourcesPurge(void);
/* Mark as used */
extern RwResEntry  *RwResourcesUseResEntry(RwResEntry * entry);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/bamemory.h ---*/

/****************************************************************************
 Defines
 */

/*
 * Debug fill bytes for compatibility with MSVC/C++ debug heap
 * See
 * \Program Files\Microsoft Visual Studio\VC98\CRT\SRC\DBGHEAP.C:
 * static unsigned char _bNoMansLandFill = 0xFD;
 *   // fill no-man's land with this
 * static unsigned char _bDeadLandFill   = 0xDD;
 *   // fill free objects with this
 * static unsigned char _bCleanLandFill  = 0xCD;
 *   // fill new objects with this
 */

#if (!defined(rwFREELISTNOMANSLANDFILL))
#define rwFREELISTNOMANSLANDFILL    0xFD
#endif /* (!defined(rwFREELISTNOMANSLANDFILL)) */

#if (!defined(rwFREELISTDEADLANDFILL))
#define rwFREELISTDEADLANDFILL      0xDD
#endif /* (!defined(rwFREELISTDEADLANDFILL)) */

#if (!defined(rwFREELISTCLEANLANDFILL))
#define rwFREELISTCLEANLANDFILL     0xCD
#endif /* (!defined(rwFREELISTCLEANLANDFILL)) */

#define RWFREELISTALIGNED(_pData, _freelist) \
  (! (((RwUInt32)(_pData)) & ((_freelist)->alignmentMinusOne)) )

/*****************************
 * REGULAR MEMORY ALLOCATION *
 *****************************/

/**
 * \ingroup rwmem
 * \def RwMalloc
 * RwMalloc(_s) is a macro for malloc(_s).
 */

/**
 * \ingroup rwmem
 * \def RwFree
 * RwFree(_p) is a macro for free(_p).
 */

/**
 * \ingroup rwmem
 * \def RwCalloc
 * RwCalloc(_n, _s) is a macro for calloc(_n, _s).
 */

/**
 * \ingroup rwmem
 * \def RwRealloc
 * RwRealloc(_p, _s) is a macro for realloc(_p, _s).
 */

#if ( (defined(RWMEMDEBUG)) && defined(RWDEBUG) )

#if (!defined(RWNOFREELISTS))
#define RWNOFREELISTS
#endif /* (!defined(RWNOFREELISTS)) */

#if (defined(rwPLUGIN_ID))
#define _CLIENT_TAG \
    ( 0xFFFF & (rwPLUGIN_ID) )
#endif /* (defined(rwPLUGIN_ID)) */

#if (!defined(_CLIENT_TAG))
#define _CLIENT_TAG \
    ( 0xFFFF & (MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x00) ) )
#endif /* (!defined(_CLIENT_TAG)) */

# if (defined(_MSC_VER))
#  if ((_MSC_VER>=1000) && defined(_DEBUG))

/* Pick up _ASSERTE() macro */
/* #include <windows.h> */
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))
#define _CRTDBG_MAP_ALLOC
#endif /* defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC)) */
#include <crtdbg.h>

#define RwMalloc(_s)                                    \
    _malloc_dbg((_s),                                   \
               _CLIENT_BLOCK | ((_CLIENT_TAG)<<16),     \
               __FILE__,                                \
               __LINE__)

#define RwFree(_p)                                      \
   _free_dbg((_p),                                      \
               _CLIENT_BLOCK | ((_CLIENT_TAG)<<16))

#define RwCalloc(_n, _s)                                \
   _calloc_dbg((_n), (_s),                              \
               _CLIENT_BLOCK | ((_CLIENT_TAG)<<16),     \
               __FILE__,                                \
               __LINE__)

#define RwRealloc(_p, _s)                               \
   _realloc_dbg((_p),                                   \
                (_s),                                   \
               _CLIENT_BLOCK | ((_CLIENT_TAG)<<16),     \
               __FILE__,                                \
               __LINE__)

#define     RWCRTORDBGFLAG(_flag)                       \
    do                                                  \
    {                                                   \
        int            _DbgFlag;                        \
                                                        \
        _DbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); \
        _DbgFlag |= (_flag);                            \
        _CrtSetDbgFlag(_DbgFlag);                       \
    }   while(0)

#define VALID_HEAP_STR \
  __FILE__##"("##RW_STRINGIFY_EXPANDED(__LINE__)##"): valid heap\n"

#define     RWCRTCHECKMEMORY()                          \
    do                                                  \
    {                                                   \
        int             valid_heap;                     \
                                                        \
        valid_heap = _CrtCheckMemory();                 \
        _ASSERTE(valid_heap);                           \
    }   while(0)

/*
 *      if (valid_heap)                                 \
 *          OutputDebugString(VALID_HEAP_STR);          \
 */

#define NO_LEAKS_FOUND_STR \
   __FILE__##"("##RW_STRINGIFY_EXPANDED(__LINE__)##"): no heap leaks found\n"

#define     RWCRTDUMPMEMORYLEAKS()                      \
    do                                                  \
    {                                                   \
        int             leaks_found;                    \
                                                        \
        leaks_found = _CrtDumpMemoryLeaks();            \
        _ASSERTE(!leaks_found);                         \
        if (!leaks_found)                               \
            OutputDebugString(NO_LEAKS_FOUND_STR);      \
    }   while(0)

#define HEAP_DIFFERENCES_FOUND_STR \
   __FILE__##"("##RW_STRINGIFY_EXPANDED(__LINE__)##"): heap differences found\n"

#define NO_DIFFERENCES_FOUND_STR \
   __FILE__##"("##RW_STRINGIFY_EXPANDED(__LINE__)##"): no heap differences found\n"

#define RWCRTHEAPDIFFERENCESINCE(_Then)                                   \
    do                                                                    \
    {                                                                     \
        /* only dump differences when                                     \
         * there are in fact differences */                               \
        _CrtMemState _Now;                                                \
        _CrtMemState _Delta;                                              \
        const int _DbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);         \
        int Differences;                                                  \
                                                                          \
        _CrtMemCheckpoint(&_Now);                                         \
        _CrtMemDifference(&_Delta, _Then, &_Now);                         \
                                                                          \
        (Differences) = ( ( 0 != _Delta.lCounts[_CLIENT_BLOCK] ) ||       \
                          ( 0 != _Delta.lCounts[_NORMAL_BLOCK] ) ||       \
                          ( (_DbgFlag & _CRTDBG_CHECK_CRT_DF) &&          \
                            ( 0 != _Delta.lCounts[_CRT_BLOCK]) ) );       \
                                                                          \
        if ( (Differences) )                                              \
        {                                                                 \
            /* difference detected: dump objects since _Then. */          \
            OutputDebugString(HEAP_DIFFERENCES_FOUND_STR);                \
            _CrtMemDumpAllObjectsSince(_Then);                            \
            _CrtMemDumpStatistics(&_Delta);                               \
        }                                                                 \
        else                                                              \
        {                                                                 \
            OutputDebugString(NO_DIFFERENCES_FOUND_STR);                  \
        }                                                                 \
    }   while (0)

#define RWCRTDBGBREAK() \
    _CrtDbgBreak()

#define RWCRTDOFORALLCLIENTOBJECTS(_f, _c) \
    _CrtDoForAllClientObjects(_f, _c)

#define RWCRTISMEMORYBLOCK(_p, _t, _r, _f, _l) \
    _CrtIsMemoryBlock(_p, _t, _r, _f, _l)

#define RWCRTISVALIDHEAPPOINTER(_p) \
    _CrtIsValidHeapPointer(_p)

#define RWCRTISVALIDPOINTER(_p, _n, _r) \
    _CrtIsValidPointer(_p, _n, _r)

#define RWCRTMEMCHECKPOINT(_s) \
    _CrtMemCheckpoint(_s)

#define RWCRTMEMDIFFERENCE(_s1, _s2, _s3) \
    _CrtMemDifference(_s1, _s2, _s3)

#define RWCRTMEMDUMPALLOBJECTSSINCE(_s) \
    _CrtMemDumpAllObjectsSince(_s)

#define RWCRTMEMDUMPSTATISTICS(_s) \
    _CrtMemDumpStatistics(_s)

#define RWCRTSETALLOCHOOK(_f) \
    _CrtSetAllocHook(_f)

#define RWCRTSETBREAKALLOC(_a) \
    _CrtSetBreakAlloc(_a)

#define RWCRTSETDBGFLAG(_f) \
    _CrtSetDbgFlag(_f)

#define RWCRTSETDUMPCLIENT(_f) \
    _CrtSetDumpClient(_f)

#define RWCRTSETREPORTFILE(_t, _f) \
    _CrtSetReportFile(_t, _f)

#define RWCRTSETREPORTHOOK(_f) \
    _CrtSetReportHook(_f)

#define RWCRTSETREPORTMODE(_t, _f) \
    _CrtSetReportMode(_t, _f)

#if (!defined(_CRTDBG_FLAGS))
#define _CRTDBG_FLAGS                                           \
    ( (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF |       \
       _CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF) &          \
     ~(_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_RESERVED_DF) )
#endif /* (!defined(_CRTDBG_FLAGS)) */

#  endif /* ((_MSC_VER>=1000) && defined(_DEBUG)) */
# endif /* (defined(_MSC_VER)) */



#if (!defined(rwDEADPTRFILL))
#define rwDEADPTRFILL      ((void *)0xDDDDDDDD)
#endif /* (!defined(rwDEADPTRFILL)) */

#endif /* (defined(RWDEBUG) && (defined(RWMEMDEBUG))) */

#if (!defined(rwDEADPTRFILL))
#define rwDEADPTRFILL      (NULL)
#endif /* (!defined(rwDEADPTRFILL)) */

#if (!defined(RwMalloc))
#define RwMalloc(_s)   ((RWSRCGLOBAL(memoryFuncs).rwmalloc)((_s)))
#endif /* (!defined(RwMalloc)) */

#if (!defined(RwFree))
#define RwFree(_p)     ((RWSRCGLOBAL(memoryFuncs).rwfree)((_p)))
#endif /* (!defined(RwFree)) */

#if (!defined(RwCalloc))
#define RwCalloc(_n, _s)   ((RWSRCGLOBAL(memoryFuncs).rwcalloc)((_n), (_s)))
#endif /* (!defined(RwCalloc)) */

#if (!defined(RwRealloc))
#define RwRealloc(_p, _s)  ((RWSRCGLOBAL(memoryFuncs).rwrealloc)((_p),(_s)))
#endif /* (!defined(RwRealloc)) */

#if (!defined(RWCRTORDBGFLAG))
#define     RWCRTORDBGFLAG(_flag) /* No op */
#endif /* (!defined(RWCRTORDBGFLAG)) */

#if (!defined(RWCRTCHECKMEMORY))
#define RWCRTCHECKMEMORY()     /* No Op */
#endif /* (!defined(RWCRTCHECKMEMORY)) */

#if (!defined(RWCRTDBGBREAK))
#define RWCRTDBGBREAK()        /* No Op */
#endif /* (!defined(RWCRTDBGBREAK)) */

#if (!defined(RWCRTDOFORALLCLIENTOBJECTS))
#define RWCRTDOFORALLCLIENTOBJECTS(_f, _c) /* No Op */
#endif /* (!defined(RWCRTDOFORALLCLIENTOBJECTS)) */

#if (!defined(RWCRTDUMPMEMORYLEAKS))
#define RWCRTDUMPMEMORYLEAKS() /* No Op */
#endif /* (!defined(RWCRTDUMPMEMORYLEAKS)) */

#if (!defined(RWCRTHEAPDIFFERENCESINCE))
#define RWCRTHEAPDIFFERENCESINCE(_Then)           /* No Op */
#endif /* (!defined(RWCRTHEAPDIFFERENCESINCE)) */

#if (!defined(RWCRTISMEMORYBLOCK))
#define RWCRTISMEMORYBLOCK(_p, _t, _r, _f, _l)    (NULL != (_p))
#endif /* (!defined(RWCRTISMEMORYBLOCK)) */

#if (!defined(RWCRTISVALIDHEAPPOINTER))
#define RWCRTISVALIDHEAPPOINTER(_p)               (NULL != (_p))
#endif /* (!defined(RWCRTISVALIDHEAPPOINTER)) */

#if (!defined(RWCRTISVALIDPOINTER))
#define RWCRTISVALIDPOINTER(_p, _n, _r)           (NULL != (_p))
#endif /* (!defined(RWCRTISVALIDPOINTER)) */

#if (!defined(RWCRTMEMCHECKPOINT))
#define RWCRTMEMCHECKPOINT(_s) /* No Op */
#endif /* (!defined(RWCRTMEMCHECKPOINT)) */

#if (!defined(RWCRTMEMDIFFERENCE))
#define RWCRTMEMDIFFERENCE(_s1, _s2, _s3) /* No Op */
#endif /* (!defined(RWCRTMEMDIFFERENCE)) */

#if (!defined(RWCRTMEMDUMPALLOBJECTSSINCE))
#define RWCRTMEMDUMPALLOBJECTSSINCE(_s) /* No Op */
#endif /* (!defined(RWCRTMEMDUMPALLOBJECTSSINCE)) */

#if (!defined(RWCRTMEMDUMPSTATISTICS))
#define RWCRTMEMDUMPSTATISTICS(_s)                (NULL)
#endif /* (!defined(RWCRTMEMDUMPSTATISTICS)) */

#if (!defined(RWCRTSETALLOCHOOK))
#define RWCRTSETALLOCHOOK(_f)                     (NULL)
#endif /* (!defined(RWCRTSETALLOCHOOK)) */

#if (!defined(RWCRTSETBREAKALLOC))
#define RWCRTSETBREAKALLOC(_a)                    (0)
#endif /* (!defined(RWCRTSETBREAKALLOC)) */

#if (!defined(RWCRTSETDBGFLAG))
#define RWCRTSETDBGFLAG(_f)                       (0)
#endif /* (!defined(RWCRTSETDBGFLAG)) */

#if (!defined(RWCRTSETDUMPCLIENT))
#define RWCRTSETDUMPCLIENT(_f)                    (NULL)
#endif /* (!defined(RWCRTSETDUMPCLIENT)) */

#if (!defined(RWCRTSETREPORTFILE))
#define RWCRTSETREPORTFILE(_t, _f)                (NULL)
#endif /* (!defined(RWCRTSETREPORTFILE)) */

#if (!defined(RWCRTSETREPORTHOOK))
#define RWCRTSETREPORTHOOK(_f)                    (NULL)
#endif /* (!defined(RWCRTSETREPORTHOOK)) */

#if (!defined(RWCRTSETREPORTMODE))
#define RWCRTSETREPORTMODE(_t, _f)                (0)
#endif /* (!defined(RWCRTSETREPORTMODE)) */

#if (!defined(RWREGSETBREAKALLOC))
#define RWREGSETBREAKALLOC(_name) /* No op */
#endif /* (!defined(RWREGSETBREAKALLOC)) */

#if (!defined(RWREGSETASSERTPRINT))
#define RWREGSETASSERTPRINT(_name) /* No op */
#endif /* (!defined(RWREGSETASSERTPRINT)) */

#if (!defined(RWGETWINREGDWORD))
#define  RWGETWINREGDWORD(_env_var, _match) /* No op */
#endif /* (!defined(RWGETWINREGDWORD)) */

#if (!defined(RWGETWINREGBINARY))
#define  RWGETWINREGBINARY(_env_var, _match) /* No op */
#endif /* (!defined(RWGETWINREGBINARY)) */

#if (!defined(RWGETWINREGSTRING))
#define  RWGETWINREGSTRING(_env_var, _match) /* No op */
#endif /* (!defined(RWGETWINREGSTRING)) */

#if (!defined(_CRTDBG_FLAGS))
#define  _CRTDBG_FLAGS 0x33
#endif /* (!defined(_CRTDBG_FLAGS)) */

/****************************************************************************
 Global Types
 */

typedef struct RwMemoryFunctions RwMemoryFunctions;
/**
 * \ingroup datatypes
 * \struct RwMemoryFunctions
 * This type represents the memory functions used
 * by RenderWare. By default, the standard ANSI functions are used. The
 * application may install an alternative interface providing that it is ANSI
 * compliant (see API function \ref RwEngineInit):
 */
struct RwMemoryFunctions
{
    /* c.f.
     * Program Files/Microsoft Visual Studio/VC98/Include/MALLOC.H
     */
    void *(*rwmalloc)(size_t size);                   /**< rwmalloc   malloc */
    void  (*rwfree)(void *mem);                       /**< rwfree     free */
    void *(*rwrealloc)(void *mem, size_t newSize);    /**< rwrealloc  realloc */
    void *(*rwcalloc)(size_t numObj, size_t sizeObj); /**< calloc     calloc */
};

typedef struct RwFreeBlock RwFreeBlock;
/*
 * Freelists -- from Page 131
 * Advanced Animation and Rendering Techniques
 * Alan Watt and Mark Watt
 * Addison-Wesley 1993,
 * ISBN 0-201-54412-1:
 *
 * "Lastly, on a more general note concerning speedups for renderers, the
 *  implementor should be aware that a lot of suggestions for improving
 *  efficiency fall into the category of ingenious, but complex,
 *  algorithms for very specific contexts that may save a few microseconds
 *  but which make your code unreadable.  A more general computer science
 *  perspective that takes a `global view' of the renderer can be more
 *  fruitful.  For example, the renderer devotes a lot of time to
 *  allocating and deallocating chunks of memory for storing data. A lot
 *  of these chunks are always the same size - such as those that are
 *  continually required to store the data structure for fragment lists.
 *  Using memory management techniques that recognize this fact can yield
 *  considerable dividends.  One such scheme would be to hold a series of
 *  empty lists in memory for all the commonly used data structures.  An
 *  empty list for fragments, say, would contain a list of previously
 *  allocated, but no longer needed, fragment structures.  When the
 *  renderer needs memory for a new fragment, it looks first at this empty
 *  list.  If there is nothing there it allocates space directly,
 *  otherwise it takes a fragments off the end of the list and uses that.
 *  Conversely, when the renderer no longer needs a fragment, instead of
 *  freeing it, it goes onto the end of the empty list.  In the authors'
 *  experience, replacing the naive allocate/deallocate scheme with this
 *  way of managing memory can result in 100% speedup. "
 */
struct RwFreeBlock
{
    RwFreeBlock        *nextBlock;
};

typedef struct RwFreeList RwFreeList;
struct RwFreeList
{
    void              **freeListStack; /* Stack of unused entries */
    void              **freeListStackTop; /* Pointer to the top of the stack */

    RwFreeBlock        *firstBlock; /* Data start */

    RwInt32             blockSize; /* Size of block in bytes */
    RwInt32             entrySize; /* Entry size */
    RwInt32             alignmentMinusOne; /* Entry alignment minus 1 */
    RwInt32             entriesPerBlock; /* Amount of space in a block */

    RwInt32             entriesAllocated; /* Total slots allocated
                                           * (but not necessarily being used */

    /* All freelists */
    RwLLLink            lFreeList;

#if (defined(RWDEBUG) && !defined(DOXYGEN))
    const RwChar       *fileCreate;
    RwUInt32            lineCreate;
#endif /* (defined(RWDEBUG) && !defined(DOXYGEN)) */
};

/**
 * \ingroup datatypes
 * \ref RwFreeListCallBack represents
 * the function called from \ref RwFreeListForAllUsed for all used entries in a
 * given free list.
 *
 * \param  pMem   Pointer to the start of the current entries.
 *
 * \param  pData   User-defined data pointer.
 *
 * \see RwFreeListForAllUsed
 *
 */
typedef void        (*RwFreeListCallBack) (void *pMem, void *pData);
typedef void       *(*RwMemoryAllocFn)    (RwFreeList * fl);
typedef RwFreeList *(*RwMemoryFreeFn)     (RwFreeList * fl, void *pData);

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

extern RwMemoryFunctions *RwOsGetMemoryInterface(void);

/*************
 * FREELISTS *
 *************/

/* Allocation and freeing */
#if (defined(RWDEBUG) && !defined(DOXYGEN))

extern RwFreeList  *_rwFreeListCreate(RwInt32 entrySize,
                                      RwInt32 entriesPerBlock,
                                      RwInt32 alignment,
                                      const RwChar *fileCreate,
                                      RwUInt32 lineCreate );

#define RwFreeListCreate(entrySize, entriesPerBlock, alignment) \
                    _rwFreeListCreate(entrySize,                \
                                      entriesPerBlock,          \
                                      alignment,                \
                                      __FILE__,                 \
                                      __LINE__)
#else /* (defined(RWDEBUG) && !defined(DOXYGEN)) */

extern RwFreeList  *RwFreeListCreate(RwInt32 entrySize,
                                     RwInt32 entriesPerBlock,
                                     RwInt32 alignment);
#endif /* (defined(RWDEBUG) && !defined(DOXYGEN)) */

extern RwBool       RwFreeListDestroy(RwFreeList * freelist);
/* Garbage collection/enumeration */
extern RwInt32      RwFreeListPurge(RwFreeList * freelist);
extern RwFreeList  *RwFreeListForAllUsed(RwFreeList * freelist,
                                         RwFreeListCallBack
                                         fpCallBack, void *pData);
extern RwInt32      RwFreeListPurgeAllFreeLists(void);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

#if (defined(RWDEBUG) && defined(RWNOFREELISTS) && !defined(RWKEEPFREELISTS))

#if ( (defined(__MWERKS__) || defined(__GNUC__))  && defined (__R5900__))

/*
 * for more on memalign, see
 * http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_3.html#SEC28
 */
#include <rtdbmalloc.h>
#define RwFreeListAlloc(_f)     memalign((1 + (_f)->alignmentMinusOne), \
                                         (_f)->entrySize)

#else                           /* ( (defined(__MWERKS__) || defined(__GNUC__))  && defined (__R5900__))  */

#define RwFreeListAlloc(_f)     RwMalloc((_f)->entrySize)

#endif                          /* ( (defined(__MWERKS__) || defined(__GNUC__))  && defined (__R5900__))  */

#define RwFreeListFree(_f, _p)  RwFree((_p))

#endif                          /* (defined(RWDEBUG) && defined(RWNOFREELISTS) && !defined(RWKEEPFREELISTS)) */

#if (!defined(RwFreeListAlloc))
#define RwFreeListAlloc(_f)     RWSRCGLOBAL(memoryAlloc)(_f)
#endif                          /* (!defined(RwFreeListAlloc)) */

#if (!defined(RwFreeListFree))
#define RwFreeListFree(_f, _p)  RWSRCGLOBAL(memoryFree)(_f, _p)
#endif                          /* (!defined(RwFreeListFree)) */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2core.h ---*/

extern RwInt32 _rwRxHeapInitialSize;

/* Beneficial padding of PowerPipe types is still being worked out... */
#define PADCLUSTERSx


/*************************************************************
 * Global Defines
 */

#define RWBOOLTOGGLE(bVar) ((bVar == FALSE)?(bVar = TRUE):(bVar = FALSE))

/* Both these currently limited due to the use of RwUInt32 bitfields */
#define RXNODEMAXCLUSTERSOFINTEREST 32
#define RXNODEMAXOUTPUTS            32

/*
 * Cluster flags
 */

#define rxCLFLAGS_NULL          ((RwUInt16) 0x0000U)
#define rxCLFLAGS_CLUSTERVALID  ((RwUInt16) 0x0001U)
#define rxCLFLAGS_EXTERNAL ((RwUInt16) 0x0002U)
#define rxCLFLAGS_EXTERNALMODIFIABLE ((RwUInt16) 0x0004U | 0x0002U)
#define rxCLFLAGS_MODIFIED ((RwUInt16) 0x0008U)

/*
 * Packet flags
 */

#define rxPKFLAGS_NULL        ((RwUInt16) 0x0000U)

/*
 * used in input specification
 */

/**
 * \ingroup rwcoregeneric
 * \ref RxClusterValidityReq
 * Flags specifying the state requirements for
 * a \ref RxCluster on entry to a node */
enum RxClusterValidityReq
{
    rxCLREQ_DONTWANT = 0, /**<The cluster is required but any data within it is
                           * not wanted and will be overwritten */
    rxCLREQ_REQUIRED = 1, /**<The cluster is required and it must contain
                           * valid data */
    rxCLREQ_OPTIONAL = 2, /**<The cluster will be used if it is present and
                           * contains valid data, otherwise the node will
                           * make do without it. */
    rxCLUSTERVALIDITYREQFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};


/**
 * \ingroup rwcoregeneric
 * \ref RxClusterValid
 * Flags specifying the state requirements for
 * a \ref RxCluster on exit from a node */
enum RxClusterValid
{
    rxCLVALID_NOCHANGE = 0, /**<The cluster and its data will not change in
                             * validity on passing through this node */
    rxCLVALID_VALID = 1,    /**<The cluster and its data will be valid on
                             * exit from this node */
    rxCLVALID_INVALID = 2,  /**<The cluster's data will be invalid on
                             * exit from this node */
    rxCLUSTERVALIDFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};

/****************************************************************************
 Global Types
 */

typedef struct RxClusterDefinition RxClusterDefinition;

typedef struct rxReq rxReq;

typedef enum RxClusterValidityReq RxClusterValidityReq;
typedef enum RxClusterValid RxClusterValid;
typedef struct RxOutputSpec RxOutputSpec;
typedef struct RxClusterRef RxClusterRef;
typedef struct RxIoSpec RxIoSpec;

typedef struct RxNodeMethods RxNodeMethods;
typedef struct RxNodeDefinition RxNodeDefinition;

typedef struct RxCluster RxCluster;
typedef struct RxPipelineCluster RxPipelineCluster;
typedef struct RxPacket RxPacket;
typedef struct RxPipelineNode RxPipelineNode;
typedef struct RxPipelineNodeTopSortData RxPipelineNodeTopSortData;
typedef struct RxPipelineNode RxPipelineNodeInstance;
typedef struct RxPipelineNodeParam RxPipelineNodeParam;
typedef struct RxExecutionContext RxExecutionContext;
typedef struct RxPipelineRequiresCluster RxPipelineRequiresCluster;
typedef struct RxPipeline RxPipeline;

/***************************************************************************
 *
 * C L U S T E R   D E F I N I T I O N
 *
 ***************************************************************************/

/**
 * \ingroup rwcoregeneric
 * \struct RxClusterDefinition
 * Structure describing a cluster */
struct RxClusterDefinition
{
    RwChar             *name;                  /**< Name */
    RwUInt32            defaultStride;         /**< Default stride */
    RwUInt32            defaultAttributes;     /**< Default attributes */
    const char         *attributeSet;           /**< Attribute set */
};


/***************************************************************************
 *
 * N O D E   D E F I N I T I O N   S T R U C T S
 *
 ***************************************************************************/

/**
 * \ingroup rwcoregeneric
 * \struct RxOutputSpec
 * Structure describing an output specification of a node */
struct RxOutputSpec
{
     RwChar             *name;                  /**< Name */
     RxClusterValid     *outputClusters;        /**< States of clusters of interest on output */
     RxClusterValid      allOtherClusters;      /**< States of clusters not of interest on output */
};



/**
 * \ingroup rwcoregeneric
 * \ref RxClusterForcePresent
 *  Flags specifying whether an \ref RxCluster
 * should be forced to be present in an \ref RxPipelineNode */
enum RxClusterForcePresent
{
    rxCLALLOWABSENT = FALSE, /**<The cluster is allowed to be absent if no prior
                              *  nodes create it and no subsequent nodes require it */
    rxCLFORCEPRESENT = TRUE, /**<The cluster must be present even if no prior
                              *  nodes create it and no subsequent nodes require it */

    rxCLUSTERFORCEPRESENTFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RxClusterForcePresent RxClusterForcePresent;

/**
 * \ingroup rwcoregeneric
 * \struct RxClusterRef
 * Structure describing a cluster reference */
struct RxClusterRef
{
    RxClusterDefinition  *clusterDef;           /**< Cluster definition */
    RxClusterForcePresent forcePresent;         /**< Specifies whether the cluster should be forced present */
    RwUInt32              reserved;             /**< Omit or initialize to zero */
};

#define rxCLRESERVED       ((RwUInt32)0)

/**
 * \ingroup rwcoregeneric
 * \struct RxIoSpec
 * Structure describing an input/output specification of a node */
struct RxIoSpec
{
    RwUInt32              numClustersOfInterest;/**< Number of Clusters of interest */
    RxClusterRef         *clustersOfInterest;   /**< Clusters of interest array */
    RxClusterValidityReq *inputRequirements;    /**< Requirements of the clusters of interest on input to the node */
    RwUInt32              numOutputs;           /**< Number of outputs from the node */
    RxOutputSpec         *outputs;              /**< Output specification array */
};

/**
 * \ingroup rwcoregeneric
 * \typedef RxNodeBodyFn
 * is the callback to be
 * called during pipeline execution -- and, typically, process
 * \ref RxPacket's -- for the owning pipeline node.
 *
 * \param  self   A pointer to the pipeline node being executed
 * \param  params   A pointer to a parameter structure
 *
 * \return TRUE on success, FALSE otherwise.
 *
 * \see RxNodeMethods
 */
typedef RwBool (*RxNodeBodyFn) (RxPipelineNode * self,
                                const RxPipelineNodeParam *params);

/**
 * \ingroup rwcoregeneric
 * \typedef RxNodeInitFn
 * is the callback to be called,
 * for the owning node definition, the first time an \ref RxPipeline
 * referencing that node definition is unlocked.
 *
 * \param  self   A pointer to the node definition
 *
 * \return TRUE on success, FALSE otherwise.
 *
 * \see RxNodeMethods
 */
typedef RwBool (*RxNodeInitFn) (RxNodeDefinition * self);

/**
 * \ingroup rwcoregeneric
 * \typedef RxNodeTermFn
 * is the callback to be called,
 * for the owning node definition, the last time an \ref RxPipeline
 * referencing that node definition is destroyed or locked.
 *
 * \param  self   A pointer to the node definition
 *
 * \see RxNodeMethods
 */
typedef void   (*RxNodeTermFn) (RxNodeDefinition * self);

/**
 * \ingroup rwcoregeneric
 * \typedef RxPipelineNodeInitFn
 * is the callback to be called, for the owning pipeline node, whenever a
 * \ref RxPipeline containing that that pipeline node is unlocked.
 *
 * \param  self   A pointer to the pipeline node
 *
 * \return TRUE on success, FALSE otherwise.
 *
 * \see RxNodeMethods
 */
typedef RwBool (*RxPipelineNodeInitFn) (RxPipelineNode * self);

/**
 * \ingroup rwcoregeneric
 * \typedef RxPipelineNodeTermFn
 * is the callback to be called, for the owning pipeline node, whenever a
 * \ref RxPipeline containing that that pipeline node is locked or
 * destroyed.
 *
 * \param  self   A pointer to the pipeline node
 *
 * \see RxNodeMethods
 */
typedef void   (*RxPipelineNodeTermFn) (RxPipelineNode * self);

/**
 * \ingroup rwcoregeneric
 * \typedef RxPipelineNodeConfigFn
 * is the callback to be called, for the owning pipeline node, whenever a
 * \ref RxPipeline containing that that pipeline node is unlocked,
 * *after* all \ref RxPipelineNodeInitFn's have been called for the
 * pipeline in question. This func is to be used as described in
 * \ref RxPipelineNodeSendConfigMsg.
 *
 * \param  self   A pointer to the pipeline node
 * \param  pipeline   A pointer to the containing pipeline
 *
 * \return TRUE on success, FALSE otherwise.
 *
 * \see RxNodeMethods
 */
typedef RwBool (*RxPipelineNodeConfigFn) (RxPipelineNode * self,
                                          RxPipeline * pipeline);

/**
 * \ingroup rwcoregeneric
 * \typedef RxConfigMsgHandlerFn
 * is the callback to be called, for the owning pipeline node, whenever
 * a message is sent to it by the \ref RxPipelineNodeConfigFn of another
 * pipeline node in the same pipeline. See \ref RxPipelineNodeSendConfigMsg.
 *
 * \param  self   A pointer to the pipeline node
 * \param  msg   Message ID
 * \param  intparam   Meaning is message-specific
 * \param  ptrparam   Meaning is message-specific
 *
 * \return A RwInt32 value, 0: unserviced; -ve: error; +ve: informative success
 *
 * \see RxNodeMethods
 */
typedef RwUInt32 (*RxConfigMsgHandlerFn) (RxPipelineNode * self,
                                          RwUInt32 msg,
                                          RwUInt32 intparam,
                                          void *ptrparam);

/**
 * \ingroup rwcoregeneric
 * \struct RxNodeMethods
 * A structure describing a set
 * of node methods
 *
 * \see RxNodeBodyFn
 * \see RxNodeInitFn
 * \see RxNodeTermFn
 * \see RxPipelineNodeInitFn
 * \see RxPipelineNodeTermFn
 * \see RxPipelineNodeConfigFn
 * \see RxConfigMsgHandlerFn
 */
struct RxNodeMethods
{
    RxNodeBodyFn         nodeBody;              /**< Node body function */
    RxNodeInitFn         nodeInit;              /**< Node initialization function */
    RxNodeTermFn         nodeTerm;              /**< Node termination function */
    RxPipelineNodeInitFn pipelineNodeInit;      /**< Pipeline node initialization function */
    RxPipelineNodeTermFn pipelineNodeTerm;      /**< Pipeline node termination function */
    RxPipelineNodeConfigFn pipelineNodeConfig;  /**< Pipleline node configuation function */
    RxConfigMsgHandlerFn configMsgHandler;      /**< Configuaraton message handler function */
};

/**
 * \ingroup rwcoregeneric
 * \ref RxNodeDefEditable
 * Flags specifying whether an \ref RxNodeDefinition
 * is editable or not (\ref RxPipelineNodeCloneDefinition,
 * \ref RxPipelineNodeReplaceCluster and \ref RxPipelineNodeRequestCluster
 * create editable copies of node definitions as the originals may be
 * static definitions). */
enum RxNodeDefEditable
{
    /**<This node definition should not be freed */
    rxNODEDEFCONST = FALSE,
    /**< This node definition is a temporary,
     * modified copy of another and can be freed */
    rxNODEDEFEDITABLE = TRUE,
    rxNODEDEFEDITABLEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RxNodeDefEditable RxNodeDefEditable;

/**
 * \ingroup rwcoregeneric
 * \struct RxNodeDefinition
 * A structure describing a node definition */
struct RxNodeDefinition
{
    RwChar             *name;                   /**< Name */
    RxNodeMethods       nodeMethods;            /**< Node methods */
    RxIoSpec            io;                     /**< Input/output specification */
    RwUInt32            pipelineNodePrivateDataSize; /**< Size in bytes of node's private data  */
    RxNodeDefEditable   editable;               /**< Flags whether a node is editable */
    RwInt32             InputPipesCnt;          /**< Count of the unlocked pipelines containing this node */
};

/***************************************************************************
 *
 * P I P E L I N E - E X E C U T I O N - T I M E   S T R U C T S
 *
 ***************************************************************************/

/**
 * \ingroup rwcoregeneric
 * \struct RxPipelineCluster
 * A structure describing a pipeline cluster;
 * that is, an \ref RxClusterDefinition in the context of a specific \ref RxPipeline
 * (in the same was as an \ref RxPipelineNode is an \ref RxNodeDefinition in the
 * context of a specific \ref RxPipeline). The \ref RxCluster is the structure
 * representing this and the \ref RxClusterDefinition within \ref RxPacket's at
 * pipeline-execution-time */
struct RxPipelineCluster
{
    RxClusterDefinition *clusterRef;            /**< Cluster refererence */
    RwUInt32             creationAttributes;    /**< Creation Attributes */
};

/**
 * \ingroup rwcoregeneric
 * \struct RxCluster
 * A structure describing a cluster; this is
 * the representative of an \ref RxClusterDefinition and \ref RxPipelineCluster
 * within \ref RxPacket's at pipeline-execution-time. */
struct RxCluster
{
    RwUInt16            flags;                  /**< Bitfield of flags e.g. modification permissions */
    RwUInt16            stride;                 /**< Stride in bytes of the cluster's data */
    void               *data;                   /**< The Cluster's data */
    void               *currentData;            /**< A 'cursor', referencing the current element in the data */
    RwUInt32            numAlloced;             /**< Allocated count */
    RwUInt32            numUsed;                /**< Used count */
    RxPipelineCluster  *clusterRef;             /**< Valid after a cluster has been locked for writing,
                                                 *   otherwise NULL. Analog of \ref RxPipelineNode and
                                                 *   its 'nodeDef' member. */
    RwUInt32            attributes;             /**< Attributes */
#ifdef PADCLUSTERS
    RwUInt32 pad[1];                            /**< Alignment padding */
#endif
};

/**
 * \ingroup rwcoregeneric
 * \struct RxPacket
 * A structure describing a packet header */
struct RxPacket
{
    RwUInt16            flags;                  /**< Flags to guide pipeline execution */
    RwUInt16            numClusters;            /**< Maximum number of clusters simultanesouly present in the current pipeline */
    RxPipeline         *pipeline;               /**< The pipeline in which this packet is embedded (the current pipeline) */
    RwUInt32           *inputToClusterSlot;     /**< LUT to locate clusters of interest in the packet */
    RwUInt32           *slotsContinue;          /**< Bitfields specifying clusters persisting to output node */
    RxPipelineCluster **slotClusterRefs;        /**< Internal Use */
#ifdef PADCLUSTERS
    RwUInt32 pad[3];                            /**< Alignment padding */
#endif
    RxCluster           clusters[1];            /**< Cluster array large enough for widest part of the pipeline */
};

/**
 * \ingroup rwcoregeneric
 * \struct RxPipelineNode
 * Structure describing a pipeline Node;
 * that is an \ref RxNodeDefinition in the context 
 * of a specific \ref RxPipeline. 
 */
struct RxPipelineNode
{
    RxNodeDefinition   *nodeDef;            /**< Node definition reference */
    RwUInt32            numOutputs;         /**< Output count */
    RwUInt32           *outputs;            /**< Output array, indexing the pipeline's array of pipeline nodes */
    RxPipelineCluster **slotClusterRefs;    /**< For packets passing through this node, SlotClusterRefs[n]
                                             * identifies the cluster to be found at index n in the packet's
                                             * Clusters[] array. These assignments are determined at pipeline
                                             * Unlock() time and are good for the life of the pipeline. */
    RwUInt32           *slotsContinue;      /**< Cluster persistance table for the node's outputs */
    void               *privateData;        /**< Pointer to the pipeline Node's private data */
    RwUInt32           *inputToClusterSlot; /**< LUT to locate clusters of interest in packets passing through this pipeline Node */
    RxPipelineNodeTopSortData *topSortData; /**< Internal Use */
};

/**
 * \ingroup rwcoregeneric
 * \struct RxPipelineNodeTopSortData
 * Structure describing data used during topological sorting 
 * during \ref RxLockedPipeUnlock ; 
 * RW users do not need to understand this */
struct RxPipelineNodeTopSortData
{
    RwUInt32            numIns;                 /**< Input count */
    RwUInt32            numInsVisited;          /**< Count of inputs visited during dependencies
                                                   propagation/cluster slot allocation */
    rxReq              *req;                    /**< Req used in dependencies propagation/cluster
                                                   slot allocation */
    void               *initializationData;     /**< Used by the pipeline node initialisation
                                                   function in setting up the Private data. */
    RwUInt32            initializationDataSize; /**< Present so that if the node is cloned
                                                   we can copy the initialisation data. */
};

/**
 * \ingroup rwcoregeneric
 * \struct RxPipelineNodeParam
 * Structure holding parameters
 * to pass to node body functions */
struct RxPipelineNodeParam
{
    void   *dataParam;   /**< The data pointer passed in to \ref RxPipelineExecute */
    RxHeap *heap;        /**< The heap associated with the current pipeline exeuction */
};

enum rxEmbeddedPacketState
{
    rxPKST_PACKETLESS = 0, /* Packet not created */
    rxPKST_UNUSED     = 1, /* Packet created and then destroyed */
    rxPKST_INUSE      = 2, /* Packet created but not yet destroyed and fetched but not yet dispatched */
    rxPKST_PENDING    = 3, /* Packet created but not destroyed and dispatched but not yet fetched */
    rxEMBEDDEDPACKETSTATEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum rxEmbeddedPacketState rxEmbeddedPacketState;

/**
 * \ingroup rwcoregeneric
 * \struct RxExecutionContext
 * Structure describing an execution context */
struct RxExecutionContext
{
    RxPipeline           *pipeline;     /**< Currently executing pipeline */
    RxPipelineNode       *currentNode;  /**< Currently executing node */
    RwInt32               exitCode;     /**< Used internally for nodes returning error codes on exit */
    RwUInt32              pad;          /**< Alignment padding */
    RxPipelineNodeParam   params;       /**< The parameters passed to node bodies */
    /*RwUInt32              pad[2];*/
};

/**
 * \ingroup rwcoregeneric
 * \struct RxPipelineRequiresCluster
 * Structure describing a pipeline requirement of a cluster */
struct RxPipelineRequiresCluster
{
    RxClusterDefinition *clusterDef;    /**< Reference to a Cluster definition */
    RxClusterValidityReq rqdOrOpt;      /**< Cluster validity requirement (rxCLREQ_DONTWANT, rxCLREQ_REQUIRED or rxCLREQ_OPTIONAL) */
    RwUInt32             slotIndex;     /**< Index into the packet's cluster array within this pipeline */
};

/**
 * \ingroup rwcoregeneric
 * \struct RxPipeline
 * Structure describing a pipeline */
struct RxPipeline
{
    RwBool                     locked;                /**< Flags whether the pipeline is locked for editing */
    RwUInt32                   numNodes;              /**< Node count */
    RxPipelineNode            *nodes;                 /**< Topologically sorted array of pipeline nodes */
    void                      *nodesBlock;            /**< Internally used block of memory */
    RwUInt32                   packetNumClusterSlots; /**< Number of slots allocated for clusters */
    rxEmbeddedPacketState      embeddedPacketState;   /**< The state of this pipeline's embedded packet */
    RxPacket                  *embeddedPacket;        /**< This pipeline's embedded packet */

    RwUInt32                   numInputRequirements;  /**< Input requirements count */
    RxPipelineRequiresCluster *inputRequirements;     /**< Input requirements array */

    RwUInt32           *superBlock;                   /**< Internally used block of memory */

    RwUInt32            entryPoint;                   /**< The index of the node which is the entry point of this pipeline */
};

/****************************************************************************
 * Global Prototypes
 */

/**
 * \ingroup rwcoregeneric
 * \typedef RxPipelineNodeOutputCallBack 
 * is the callback function supplied 
 * to \ref RxPipelineNodeForAllConnectedOutputs.
 *
 * The ballback will be passed a pointer to the \ref RxPipelineNode whose
 * outputs are being traversed and a pointer to the current output
 * \ref RxPipelineNode, as well as a pointer to an optional user-defined
 * data structure (callbackdata). If no such structure was specified, this
 * will be NULL.
 *
 * \param  node   Pointer to the pipeline node whose outputs
 * are being traversed.
 * \param  outputnode   Pointer to the current output
 * pipeline node.
 * \param  callbackdata   Pointer to optional user-supplied data.
 *
 * \return Returns a pointer to the \ref RxPipelineNode whose outputs are being
 * traversed, or NULL to terminate traversal.
 */
typedef RxPipelineNode * (*RxPipelineNodeOutputCallBack) (RxPipelineNode * node,
                                                  RxPipelineNode * outputnode,
                                                  void *callbackdata);

#ifdef RWDEBUG
#define RXCHECKFORUSERTRAMPLING(_pipeline)                       \
    ( _rwPipelineCheckForTramplingOfNodePrivateSpace(_pipeline) )
#endif /* RWDEBUG */

#if (!defined(RXCHECKFORUSERTRAMPLING))
#define RXCHECKFORUSERTRAMPLING(_pipeline) /* No op */
#endif /* (!defined(RXCHECKFORUSERTRAMPLING)) */


#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

extern RwBool
_rxPipelineOpen(void);

extern RwBool
_rxPipelineClose(void);

extern RwBool
rxPipelinePluginsAttach(void);

extern RxPipeline *
RxPipelineCreate(void);


extern void
_rxPipelineDestroy(RxPipeline * Pipeline);

#define _RxPipelineDestroy(_ppln)  _rxPipelineDestroy(_ppln)
#define RxPipelineDestroy(_ppln) (_rxPipelineDestroy(_ppln), TRUE)

extern RxHeap      *
RxHeapGetGlobalHeap(void);

extern RxPipeline *
RxPipelineExecute(RxPipeline  * pipeline,
                  void        * data,
                  RwBool       heapReset);

extern RxPacket *
RxPacketCreate(RxPipelineNode * node);

extern RxCluster   *
RxClusterSetStride(RxCluster * cluster,
                   RwInt32 stride);

extern RxCluster   *
RxClusterSetExternalData(RxCluster * cluster,
                         void *data,
                         RwInt32 stride,
                         RwInt32 numElements);

extern RxCluster   *
RxClusterSetData(RxCluster * cluster,
                 void *data,
                 RwInt32 stride,
                 RwInt32 numElements);

/* underlying PacketDestroy function */
extern void
_rxPacketDestroy(RxPacket * Packet);

/* more convenient parameterization */
#define RxPacketDestroy(pk, self) \
    ( _rxPacketDestroy(pk) )

#if (defined(RWDEBUG))
extern RxPacket *RxPacketFetch(RxPipelineNode * Node);
extern void      RxPacketDispatch(RxPacket * packet,
                                  RwUInt32 output,
                                  RxPipelineNode * self);
extern void      RxPacketDispatchToPipeline(RxPacket * packet,
                                            RxPipeline * dest,
                                            RxPipelineNode * self);
#else /* (defined(RWDEBUG)) */
#define RxPacketFetch(_self) \
    rxPacketFetchMacro(_self)
#define RxPacketDispatch(     _packet, _output, _self) \
    rxPacketDispatchMacro(_packet, _output, _self)
#define RxPacketDispatchToPipeline(     _packet, _pipeline, _self) \
    rxPacketDispatchToPipelineMacro(_packet, _pipeline, _self)
#endif /* (defined(RWDEBUG)) */

#define RxClusterInitialiseData(_clstr, _nmlmnts, _strd) \
    ( RxClusterInitializeData((_clstr), (_nmlmnts), (_strd)) )
extern RxCluster   *
RxClusterInitializeData(RxCluster *cluster, RwUInt32 numElements, RwUInt16 stride);

extern RxCluster   *
RxClusterResizeData(RxCluster *CurrentCluster, RwUInt32 NumElements);

extern RxCluster   *
RxClusterDestroyData(RxCluster *CurrentCluster);

#if (defined(RWDEBUG))

extern RxCluster *RxClusterLockRead(RxPacket * packet, RwUInt32 clusterIndex);

#else  /* !RWDEBUG */

#define RXCLSLOT(PKT, CLIND)             \
    ((PKT)->inputToClusterSlot[(CLIND)])

#define RxClusterLockRead(PKT, CLIND)                               \
    ( (((RwInt32)RXCLSLOT(PKT, CLIND)) == -1) ?                     \
      ((RxCluster *)NULL) :                                         \
      (RxClusterResetCursor(&PKT->clusters[RXCLSLOT(PKT, CLIND)]),  \
       &PKT->clusters[RXCLSLOT(PKT, CLIND)]) )

#endif /* !RWDEBUG */

extern RxCluster   *
RxClusterLockWrite(RxPacket * packet,
                   RwUInt32 clusterIndex,
                   RxPipelineNode * node);

extern void
RxClusterUnlock(RxCluster * cluster);

extern RwUInt32
RxPipelineNodeSendConfigMsg(RxPipelineNode * dest,
                            RwUInt32 msg,
                            RwUInt32 intparam,
                            void *ptrparam);

extern RxPipelineNode *
RxPipelineNodeForAllConnectedOutputs(RxPipelineNode * node,
                                     RxPipeline * pipeline,
                                     RxPipelineNodeOutputCallBack callbackfn,
                                     void *callbackdata);

/* Cluster attributes api [pipeline construction time] */

extern RxPipelineCluster *
RxPipelineNodeGetPipelineCluster(RxPipelineNode *node,
                                   RwUInt32 clustersOfInterestIndex);

extern RwUInt32
RxPipelineClusterGetCreationAttributes(RxPipelineCluster *cluster);

extern RxPipelineCluster *
RxPipelineClusterSetCreationAttributes(RxPipelineCluster *cluster,
                                         RwUInt32 creationAttributes);

/* Cluster attributes api [pipeline execution time] */

extern RwUInt32
RxClusterGetAttributes(RxCluster *cluster);

extern RxCluster *
RxClusterSetAttributes(RxCluster *cluster, RwUInt32 attributes);


extern void
_rxEmbeddedPacketBetweenPipelines(RxPipeline * fromPipeline,
                                 RxPipeline * toPipeline);

extern RxPipelineNode *
_rxEmbeddedPacketBetweenNodes(RxPipeline     *pipeline,
                             RxPipelineNode *nodeFrom,
                             RwUInt32        whichOutput);

extern RxExecutionContext _rxExecCtxGlobal;

/* Summary of dispatch rules:
 * o nodes that never fetch are safe to dispatch NULL, whether
 *   nodes above pass them a packet or not
 * o if you destroy the packet you can dispatch(NULL,,)
 * o if you fetch/create and dispatch(NULL), it doesn't really
 *   matter - the packet'll get passed on anyway */

#define rxPacketDispatchMacro(_packet, _output, _self)                      \
MACRO_START                                                                 \
{                                                                           \
    RxPipeline *curPipeline = _rxExecCtxGlobal.pipeline;                    \
                                                                            \
    /* _packet is now an obsolete parameter */                              \
                                                                            \
    if ( FALSE != _rxExecCtxGlobal.exitCode )                               \
    {                                                                       \
        RxPipelineNode *nextNode =                                          \
            _rxEmbeddedPacketBetweenNodes(curPipeline,                      \
                                         _self,                             \
                                         (_output));                        \
        if ( nextNode != NULL )                                             \
        {                                                                   \
            RwUInt32 exitCode =                                             \
                nextNode->nodeDef->nodeMethods.nodeBody(                    \
                    nextNode, &(_rxExecCtxGlobal.params));                  \
            /* Don't overwrite 'error' with 'success' */                    \
            if (FALSE == exitCode) _rxExecCtxGlobal.exitCode = exitCode;    \
        }                                                                   \
    }                                                                       \
    if ( curPipeline->embeddedPacketState > rxPKST_UNUSED                   \
         /* !UNUSED and !PACKETLESS */ )                                    \
    {                                                                       \
        curPipeline->embeddedPacketState = rxPKST_INUSE;                    \
        _rxPacketDestroy(curPipeline->embeddedPacket);                      \
    }                                                                       \
}                                                                           \
MACRO_STOP

/* TODO: Self redundant here... */
#define rxPacketDispatchToPipelineMacro(_packet, _pipeline, _self)          \
MACRO_START                                                                 \
{                                                                           \
    RxPipeline *toPipeline = (_pipeline);                                   \
                                                                            \
    /* _packet is now an obsolete parameter */                              \
                                                                            \
    if ( FALSE != _rxExecCtxGlobal.exitCode )                               \
    {                                                                       \
        RwUInt32 exitCode;                                                  \
        RxPipeline *fromPipeline = _rxExecCtxGlobal.pipeline; /* save */    \
        _rxEmbeddedPacketBetweenPipelines(fromPipeline,                     \
                                         toPipeline);                       \
        _rxExecCtxGlobal.pipeline = toPipeline; /* modify */                \
        exitCode =                                                          \
            toPipeline->nodes[0].nodeDef->nodeMethods.nodeBody(             \
                &toPipeline->nodes[0], &(_rxExecCtxGlobal.params));         \
        if ( FALSE == exitCode ) _rxExecCtxGlobal.exitCode = exitCode;      \
        _rxExecCtxGlobal.pipeline = fromPipeline; /* restore */             \
    }                                                                       \
    if ( toPipeline->embeddedPacketState > rxPKST_UNUSED                    \
         /* !UNUSED and !PACKETLESS */ )                                    \
    {                                                                       \
        toPipeline->embeddedPacketState = rxPKST_INUSE;                     \
        _rxPacketDestroy(toPipeline->embeddedPacket);                       \
    }                                                                       \
}                                                                           \
MACRO_STOP

#define rxPacketFetchMacro(_node)                                           \
    ( ((_rxExecCtxGlobal.pipeline)->embeddedPacketState == rxPKST_PENDING) ?\
      ((_rxExecCtxGlobal.pipeline)->embeddedPacketState = rxPKST_INUSE,     \
       (_rxExecCtxGlobal.pipeline)->embeddedPacket) :                       \
      (NULL) )

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2define.h ---*/

/**
 * \ingroup rwcoregeneric
 * \typedef RxNodeOutput 
 * typedef for a reference to an output of a pipeline node */
typedef RwUInt32       *RxNodeOutput;

/**
 * \ingroup rwcoregeneric
 * \typedef RxNodeInput 
 *  typedef for a reference to the input of a pipeline node */
typedef RxPipelineNode *RxNodeInput;

/**
 * \ingroup rwcoregeneric
 * \typedef RxLockedPipe
 * typedef for a reference to a locked pipeline 
 */
typedef RxPipeline      RxLockedPipe;


#ifdef    __cplusplus
extern "C"
{
#endif /* __cplusplus */

/* PIPELINENODE API */

extern RxNodeOutput RxPipelineNodeFindOutputByName(RxPipelineNode *node, 
                                                   const char *outputname);
extern RxNodeOutput RxPipelineNodeFindOutputByIndex(RxPipelineNode *node,
                                                    RwUInt32 outputindex);
extern RxNodeInput  RxPipelineNodeFindInput(RxPipelineNode *node);

extern RxNodeDefinition *
RxPipelineNodeCloneDefinition(RxPipelineNode *node,
                              RxClusterDefinition *cluster2add);

extern RxPipeline *
RxPipelineNodeRequestCluster(RxPipeline *pipeline,
                             RxPipelineNode *node,
                             RxClusterDefinition *clusterDef);
extern RxPipeline *
RxPipelineNodeReplaceCluster(RxPipeline *pipeline,
                             RxPipelineNode *node,
                             RxClusterDefinition *oldClusterDef,
                             RxClusterDefinition *newClusterDef);

extern void *RxPipelineNodeGetInitData(RxPipelineNode *node);
extern void *RxPipelineNodeCreateInitData(RxPipelineNode *node,
                                          RwUInt32 size);

/* PIPELINE MANIPULATION API */

extern RxPipeline     *RxPipelineClone(RxPipeline *pipeline);

extern RxPipelineNode *RxPipelineFindNodeByName(RxPipeline *pipeline, 
                                                const RwChar *name,
                                                RxPipelineNode *start,
                                                RwInt32 *index);
extern RxPipelineNode *RxPipelineFindNodeByIndex(RxPipeline *pipeline,
                                                 RwUInt32 nodeindex);

extern RxLockedPipe   *RxPipelineLock(RxPipeline *pipeline);
extern RxPipeline     *RxLockedPipeUnlock(RxLockedPipe *pipeline);

extern RxLockedPipe   *RxLockedPipeAddFragment(RxLockedPipe *pipeline,
                                               RwUInt32 *firstIndex,
                                               RxNodeDefinition *nodeDef0,
                                               ...);

extern RxPipeline     *RxLockedPipeReplaceNode(RxLockedPipe *pipeline,
                                               RxPipelineNode *node,
                                               RxNodeDefinition *nodeDef);
extern RxPipeline     *RxLockedPipeDeleteNode(RxLockedPipe *pipeline,
                                              RxPipelineNode *node);

extern RxPipeline     *RxLockedPipeSetEntryPoint(RxLockedPipe *pipeline,
                                                 RxNodeInput in);

extern RxPipelineNode *RxLockedPipeGetEntryPoint(RxLockedPipe *pipeline);

extern RxPipeline     *RxLockedPipeAddPath(RxLockedPipe *pipeline,
                                           RxNodeOutput out,
                                           RxNodeInput in);
extern RxPipeline     *RxLockedPipeDeletePath(RxLockedPipe *pipeline,
                                              RxNodeOutput out,
                                              RxNodeInput in);

extern RxPipeline     *RxPipelineInsertDebugNode(RxPipeline *pipeline,
                                                 RxPipelineNode *before,
                                                 RxPipelineNode *after,
                                                 RxNodeDefinition *debugNode);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2altmdl.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeTransform.h ---*/

#if (!defined(RXPIPELINE))
#define RXPIPELINE
#endif /* (!defined(RXPIPELINE)) */

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition *RxNodeDefinitionGetTransform(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeSubmitTriangle.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition * RxNodeDefinitionGetSubmitTriangle(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeSubmitLine.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition * RxNodeDefinitionGetSubmitLine(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeScatter.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition * RxNodeDefinitionGetScatter(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeClone.h ---*/

typedef struct RxPacketCacheCluster RxPacketCacheCluster;

/**
 * \ingroup rwcoregeneric
 * \struct RxPacketCacheCluster
 * structure containing a cache of an \ref RxCluster's
 * within an \ref RxPacketCache 
 */
struct RxPacketCacheCluster
{
    RwUInt32            slot;       /**< A \ref RwUInt32 index into the \ref RxPacketCache's
                                     * array of RxPacketCacheCluster's */
    RwUInt16            flags;      /**< A cache of the original cluster's flags */
    RwUInt16            stride;     /**< A cache of the original cluster's stride */
    void               *data;       /**< A cache of the original cluster's data */
    RwUInt32            numAlloced; /**< A cache of the original cluster's numAlloced */
    RwUInt32            numUsed;    /**< A cache of the original cluster's numUsed */
    RxPipelineCluster  *clusterRef; /**< A cache of the original cluster's \ref RxPipelineCluster */
};
typedef struct RxPacketCache RxPacketCache;

/**
 * \ingroup rwcoregeneric
 * \struct RxPacketCache
 * structure containing a cache of a \ref RxPacket */
struct RxPacketCache
{
    RwUInt16             packetFlags; /**< A cache of the original packet's flags */
    RwUInt16             pad[1];      /**< Alignment padding */
    RwUInt32             numClusters; /**< The number of present clusters in the
                                       * original packet when it was cloned */
    RwBool               lastCloneDone;/**< Once the cache has been cloned by \ref RxPacketCacheClone
                                       * with (lastClone == TRUE), it should not be used again! */
    RwUInt32             pad2[1];      /**< Alignment padding */
    RxPacketCacheCluster clusters[1]; /**< An array of \ref RxPacketCacheCluster's,
                                       * extending beyond 1 element */
};
    

typedef struct RxNodeCloneInitData RxNodeCloneInitData;
/**
 * \ingroup rwcoregeneric
 * \struct RxNodeCloneInitData
 * structure with which to initialize 
 * clone a \ref RxNodeDefinition, 
 * through \ref RxNodeDefinitionCloneCreate and
 * set up cloned \ref RxPipelineNode modes, through
 * \ref RxPipelineNodeCloneDefineModes */
struct RxNodeCloneInitData
{
    RwUInt32   numModes;   /**< Specifies the number of modes in
                              which the node should operate */
    RwUInt32   numOutputs; /**< Specifies the number of outputs of this
                              Clone node, which is also the maximum
                              number of outputs to which any one mode
                              may dispatch packets */
    RwUInt32  *modeSizes;  /**< Specifies the number of outputs to which
                              each mode dispatches packets */
    RwUInt32 **modes;      /**< An array of numModes pointers to arrays
                              (of length numOutputs) specifying the
                              outputs, in order, to which each mode
                              should dispatch packets (output zero is
                              the first output) */
};

/**
 * \ingroup rwcoregeneric
 * \struct RxNodeCloneData
 * structure which is the private
 * data of Clone nodes \ref RxPipelineNode */
typedef struct RxNodeCloneData RxNodeCloneData;
struct RxNodeCloneData
{
    RwBool optimized;         /**< \ref RwBool specifying whether \ref RxPipelineNodeCloneOptimize
                               * has been run on this \ref RxPipelineNode yet */
    RwUInt32 currentMode;     /**< \ref RwUInt32 The current mode of operation */
    RxNodeCloneInitData *data;/**< A pointer to \ref RxNodeCloneInitData data
                               * specifying the modes of operation */
};

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition *RxNodeDefinitionCloneCreate(RxNodeCloneInitData *data);
extern RwBool            RxPipelineNodeCloneDefineModes(
                             RxPipeline          *pipeline,
                             RxPipelineNode      *node,
                             RxNodeCloneInitData   *data);
extern RwBool            RxNodeDefinitionCloneDestroy(RxNodeDefinition *def);
extern RwBool            RxPipelineNodeCloneOptimize(RxPipeline     *pipeline,
                                                     RxPipelineNode *node);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeImmStash.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition *RxNodeDefinitionGetImmStash(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeImmRenderSetup.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition * RxNodeDefinitionGetImmRenderSetup(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeImmMangleTriangleIndices.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition *RxNodeDefinitionGetImmMangleTriangleIndices(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeImmMangleLineIndices.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition * RxNodeDefinitionGetImmMangleLineIndices(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeImmInstance.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition * RxNodeDefinitionGetImmInstance(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeCullTriangle.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition * RxNodeDefinitionGetCullTriangle(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeClipTriangle.h ---*/

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition *RxNodeDefinitionGetClipTriangle(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeClipLine.h ---*/

#ifdef __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

extern RxNodeDefinition *RxNodeDefinitionGetClipLine(void);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/bastream.h ---*/

/****************************************************************************
 Defines
 */

#define rwSTREAMSTACKSIZE    512

/****************************************************************************
 Global Types
 */

/**
 * \ingroup datatypes
 * \ref RwStreamType 
 * This type represents the different types of stream that 
 * can be used. 
 * See API section \ref rwstream 
 */
enum RwStreamType
{
    rwNASTREAM = 0,     /**<Invalid stream type */
    rwSTREAMFILE,       /**<File */
    rwSTREAMFILENAME,   /**<File name */
    rwSTREAMMEMORY,     /**<Memory*/
    rwSTREAMCUSTOM,     /**<Custom */
    rwSTREAMTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwStreamType RwStreamType;

/**
 * \ingroup datatypes
 * \ref RwStreamAccessType 
 * This type represents the options available for 
 * accessing a stream when it is opened.
 * See API section \ref rwstream */
enum RwStreamAccessType
{
    rwNASTREAMACCESS = 0,   /**<Invalid stream access */
    rwSTREAMREAD,           /**<Read */
    rwSTREAMWRITE,          /**<Write */
    rwSTREAMAPPEND,         /**<Append */
    rwSTREAMACCESSTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwStreamAccessType RwStreamAccessType;

/* Memory stream */
/**
 * \ingroup datatypes
 * \typedef RwStreamMemory
 * This should be considered an opaque type.
 * Use the RwStream API functions to access.
 */
typedef struct RwStreamMemory RwStreamMemory;
#if (!defined(DOXYGEN))
struct RwStreamMemory
{
    RwUInt32            position; /* Current 'memory' position 0 is first byte */
    RwUInt32            nSize;  /* Space allocated currently */
    RwUInt8            *memBlock; /* Current memory block pointer */
};
#endif /* (!defined(DOXYGEN)) */


typedef union RwStreamFile RwStreamFile;
/**
 * \ingroup datatypes
 * \union RwStreamFile 
 * This type is used to represent a file pointer for
 * accessing data on disk through the stream mechanism.
 * See API section \ref rwstream. */
union RwStreamFile
{
    void    *fpFile;               /**< file pointer */
    const void    *constfpFile;    /**< const file pointer */
};


/* Custom stream function pointer types */
typedef             RwBool(*rwCustomStreamFnClose) (void *data);
typedef             RwUInt32(*rwCustomStreamFnRead) (void *data, void *buffer,
                                                     RwUInt32 length);
typedef             RwBool(*rwCustomStreamFnWrite) (void *data,
                                                    const void *buffer,

                                                    RwUInt32 length);
typedef             RwBool(*rwCustomStreamFnSkip) (void *data,

                                                   RwUInt32 offset);

/* Custom stream */
/**
 * \ingroup datatypes
 * \typedef  RwStreamCustom
 * This should be considered an opaque type.
 * Use the RwStream API functions to access.
 */
typedef struct RwStreamCustom RwStreamCustom;
#if (!defined(DOXYGEN))
struct RwStreamCustom
{
    rwCustomStreamFnClose sfnclose;
    rwCustomStreamFnRead sfnread;
    rwCustomStreamFnWrite sfnwrite;
    rwCustomStreamFnSkip sfnskip;
    void               *data;
};
#endif /* (!defined(DOXYGEN)) */

/* Stream */

typedef union RwStreamUnion RwStreamUnion;
/**
 * \ingroup datatypes
 * \union RwStreamUnion
 * The union of all supported stream types
 */
union RwStreamUnion
{
    RwStreamMemory      memory; /**< memory */
    RwStreamFile        file; /**< file */
    RwStreamCustom      custom; /**< custom */
};

#ifdef RWASYNCSTREAMS

/* Blocking Mode */
enum RwStreamBlockMode
{
    rwSTREAMBLOCK = 0,
    rwSTREAMNOBLOCK,
    rwSTREAMBLOCKMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
}
typedef enum RwStreamBlockMode RwStreamBlockMode;

typedef struct rwStreamStack rwStreamStack;
struct rwStreamStack
{
    RwBool              callbackRunning;
    RwBool              callbackDeferred;
    RwInt32             deferredIOResult;
    struct rwStreamStackEntry *stackpointer;
    RwUInt8             stack[rwSTREAMSTACKSIZE];
};



#endif /*RWASYNCSTREAMS*/

/**
 * \ingroup datatypes
 * \typedef RwStream 
 * Binary stream for reading or writing object data. 
 * This should be considered an opaque type.
 * Use the RwStream API functions to access.
 */
typedef struct RwStream RwStream;
#if (!defined(DOXYGEN))
struct RwStream
{
    RwStreamType        type;
    RwStreamAccessType  accessType;
    RwInt32             position;
    RwStreamUnion       Type;
#ifdef RWASYNCSTREAMS
    RwStreamBlockMode   blockMode;
    rwStreamStack       stack;
#endif                    /*RWASYNCSTREAMS*/
    RwBool              rwOwned;
};
#endif /* (!defined(DOXYGEN)) */

#ifdef RWASYNCSTREAMS

/* Stream Completion Callback Function Type*/
typedef void (*RwStreamCallback)(RwStream * stream, RwInt32 ioResult,
                                 void *userData);
#endif /*RWASYNCSTREAMS*/

typedef struct RwMemory RwMemory;
/**
 * \ingroup datatypes
 * \struct RwMemory
 * This type represents a block of allocated memory.
 * It is used to specify an area of memory connected to a stream of type
 * rwSTREAMMEMORY.
 * See \ref rwstream */
struct RwMemory
{
    RwUInt8     *start; /**< starting address */
    RwUInt32    length; /**< length in bytes*/
};


/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

/* Open/Close streams */

extern RwStream *
_rwStreamInitialize(RwStream *stream,
                    RwBool rwOwned,
                    RwStreamType type,
                    RwStreamAccessType accessType,
                    const void *pData);

extern RwStream *
RwStreamOpen(RwStreamType type,
             RwStreamAccessType accessType,
             const void *pData);

extern RwBool       
RwStreamClose(RwStream * stream,
              void *pData);


/* Stream read/write */
extern RwUInt32     
RwStreamRead(RwStream * stream,
             void *buffer,
             RwUInt32 length);

extern RwStream *
RwStreamWrite(RwStream * stream,
              const void *buffer,
              RwUInt32 length);


/* Stream skipping */
extern RwStream *
RwStreamSkip(RwStream * stream,
             RwUInt32 offset);


/* Stream Asynchronous Extensions */
#ifdef RWASYNCSTREAMS
extern RwBool       
RwStreamSetBlockMode(RwStream * stream,
                     RwStreamBlockMode mode);


extern void *
RwStreamAllocCallback(RwStream * stream,
                      RwStreamCallback callback,
                      RwInt16 userdatasize);

extern void         
RwStreamReleaseCallback(RwStream * stream,
                        RwInt32 result);


extern RwBool       
RwStreamSetCallbackBreakPoint(RwStream * stream,
                              RwBool enable);

#endif                    /*RWASYNCSTREAMS*/

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/batkreg.h ---*/

/****************************************************************************
 Global Types
 */

/**
 * \ingroup datatypes
 * \ref RwPluginDataChunkWriteCallBack represents the function
 * registered by \ref RwCameraRegisterPluginStream, etc. as the function that
 * writes extension data to a binary stream.
 *
 * \param  stream   Pointer to the binary stream
 *
 * \param  binaryLength   A RwInt32 value equal to the binary
 * size (in bytes) of the extension data that will be written to the binary
 * stream.
 *
 * \param  object   Pointer to the object containing the extension
 * data.
 *
 * \param  offsetInObject   A RwInt32 value equal to the byte
 * offset of the extension data in the object.
 *
 * \param  sizeInObject   A RwInt32 value equal to the size
 * (in bytes) of the extension data.
 *
 * \return Pointer to the stream
 */
typedef RwStream *(*RwPluginDataChunkWriteCallBack)(RwStream *stream, RwInt32 binaryLength, const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);

/**
 * \ingroup datatypes
 * \ref RwPluginDataChunkReadCallBack represents the function
 * registered by \ref RwCameraRegisterPluginStream, etc. as the function that
 * reads extension data from a binary stream.
 * 
 * \param  stream   Pointer to the binary stream
 *
 * \param  binaryLength   A RwInt32 value equal to the binary
 * size (in bytes) of the extension data that will be read from a binary
 * stream.
 *
 * \param  object   Pointer to the object containing the extension
 * data.
 *
 * \param  offsetInObject   A RwInt32 value equal to the byte
 * offset of the extension data in the object.
 *
 * \param  sizeInObject   A RwInt32 value equal to the size
 * (in bytes) of the extension data.
 *
 * \return Pointer to the stream
 */
typedef RwStream *(*RwPluginDataChunkReadCallBack)(RwStream *stream, RwInt32 binaryLength, void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);

/**
 * \ingroup datatypes
 * \ref RwPluginDataChunkGetSizeCallBack represents the callback
 * registered by \ref RwCameraRegisterPluginStream, etc. as the function that
 * determines the binary size of the extension data.
 * 
 * \param  object   Pointer to the object containing the extension data.
 *
 * \param  offsetInObject   A RwInt32 value equal to the byte
 * offset of the extension data in the object.
 *
 * \param  sizeInObject   A RwInt32 value equal to the size
 * (in bytes) of the extension data.
 * 
 * \return A RwInt32 value equal to the size in bytes of the plugin extension data.
 */
typedef RwInt32(*RwPluginDataChunkGetSizeCallBack)(const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);

/**
 * \ingroup datatypes
 * \ref RwPluginDataChunkAlwaysCallBack represents the callback
 * registered by \ref RwCameraSetStreamAlwaysCallBack, etc. as the
 * function that is called after the reading of plugin stream data is
 * finished (useful to set up plugin data for plugins that found no
 * data in the stream, but that cannot set up the data during the
 * \ref RwPluginObjectConstructor callback).
 * 
 * \param  object   Pointer to the object containing the extension data.
 *
 * \param  offsetInObject   A RwInt32 value equal to the byte
 * offset of the extension data in the object.
 *
 * \param  sizeInObject   A RwInt32 value equal to the size
 * (in bytes) of the extension data.
 */
typedef RwBool(*RwPluginDataChunkAlwaysCallBack)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);

/**
 * \ingroup datatypes
 * \ref RwPluginObjectConstructor represents the callback
 * registered by \ref RwEngineRegisterPlugin, \ref RwCameraRegisterPlugin, etc.
 * as the function that initializes either the global extension data (in the
 * case of \ref RwEngineRegisterPlugin) or the object extension data (in all
 * other cases). Registered by \ref RwCameraSetStreamAlwaysCallBack, etc.
 * 
 * \param  object   Pointer to the object (global or otherwise)
 * that contains the extension data.
 *
 * \param  offsetInObject   A RwInt32 value equal to the
 * byte offset of the extension data in the object.
 *
 * \param  sizeInObject   A RwInt32 value equal to the size
 * (in bytes) of the extension data.
 *
 * \return Pointer to the object
 */
typedef void *(*RwPluginObjectConstructor)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);

/**
 * \ingroup datatypes
 * \ref RwPluginObjectCopy represents the callback registered by
 * \ref RwCameraRegisterPlugin, etc. as the function that copies the object
 * extension data when an object is duplicated.
 * 
 * \param  dstObject   Pointer to the destination object that will
 * receive the extension data.
 *
 * \param  srcObject   Pointer to the source object containing
 * extension data.
 *
 * \param  offsetInObject   A RwInt32 value equal to the byte offset
 * of the extension data in the object.
 *
 * \param  sizeInObject   A RwInt32 value equal to the size
 * (in bytes) of the extension data.
 *
 * \return Pointer to the object
 */
typedef void *(*RwPluginObjectCopy)(void *dstObject, const void *srcObject, RwInt32 offsetInObject, RwInt32 sizeInObject);

/**
 * \ingroup datatypes
 * \ref RwPluginObjectDestructor represents the callback registered
 * by \ref RwEngineRegisterPlugin, \ref RwCameraRegisterPlugin, etc. as the
 * function that destroys either the global extension data (in the case of
 * \ref RwEngineRegisterPlugin) or the object extension data (in all other
 * cases).
 * 
 * \param  object   Pointer to the object (global or otherwise)
 * containing the extension data.
 *
 * \param  offsetInObject   A RwInt32 value equal to the byte
 * offset of the extension data in the object.
 *
 * \param  sizeInObject   A RwInt32 value equal to the size
 * (in bytes) of the extension data.
 *
 * \return Pointer to the object.
 */
typedef void *(*RwPluginObjectDestructor)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);

typedef void *(*RwPluginErrorStrCallBack)(void *);

typedef struct RwPluginRegistry RwPluginRegistry;
typedef struct RwPluginRegEntry RwPluginRegEntry;

struct RwPluginRegistry
{
    RwInt32          sizeOfStruct;
    RwInt32          origSizeOfStruct;
    RwInt32          maxSizeOfStruct;
    RwInt32          staticAlloc;
    RwPluginRegEntry *firstRegEntry;
    RwPluginRegEntry *lastRegEntry;
};

struct RwPluginRegEntry
{
    RwInt32         offset;
    RwInt32         size;
    RwUInt32        pluginID;
    RwPluginDataChunkReadCallBack readCB;
    RwPluginDataChunkWriteCallBack writeCB;
    RwPluginDataChunkGetSizeCallBack getSizeCB;
    RwPluginDataChunkAlwaysCallBack alwaysCB;
    RwPluginObjectConstructor constructCB;
    RwPluginObjectDestructor destructCB;
    RwPluginObjectCopy copyCB;
    RwPluginErrorStrCallBack errStrCB;
    RwPluginRegEntry *nextRegEntry;
    RwPluginRegEntry *prevRegEntry;
    RwPluginRegistry *parentRegistry;
};



/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern          "C"
{
#endif         /* __cplusplus */


/* Registering toolkits and allocating memory */
extern RwBool
_rwPluginRegistrySetStaticPluginsSize(RwPluginRegistry * reg, 
                                      RwInt32 size);
extern RwInt32
_rwPluginRegistryAddPlugin(RwPluginRegistry * reg,
                           RwInt32 size,
                           RwUInt32 pluginID,
                           RwPluginObjectConstructor constructCB,
                           RwPluginObjectDestructor destructCB,
                           RwPluginObjectCopy copyCB);
extern RwInt32
_rwPluginRegistryGetPluginOffset(const RwPluginRegistry *reg, 
                                RwUInt32 pluginID);

/* Initializing/De-initializing instances */
extern const
RwPluginRegistry *_rwPluginRegistryInitObject(const RwPluginRegistry * reg, 
                                             void *object);
extern const
RwPluginRegistry *_rwPluginRegistryDeInitObject(const RwPluginRegistry * reg, 
                                               void *object);
extern const
RwPluginRegistry *_rwPluginRegistryCopyObject(const RwPluginRegistry * reg,
                                             void *dstObject, 
                                             const void *srcObject);

#ifdef RWDEBUG
extern RwBool
_rwPluginRegistryValidateObject(const RwPluginRegistry * reg, 
                               const void *object);
#endif         /* RWDEBUG */


#ifdef    __cplusplus
}
#endif         /* __cplusplus */

/* Compatibility macros */

#define rwPluginRegistryOpen() \
       _rwPluginRegistryOpen()
#define rwPluginRegistryClose() \
       _rwPluginRegistryClose()
#define rwPluginRegistrySetStaticPluginsSize(reg, size) \
       _rwPluginRegistrySetStaticPluginsSize(reg, size)
#define rwPluginRegistryAddPlugin(reg, size, pluginID, constructCB, destructCB, copyCB) \
       _rwPluginRegistryAddPlugin(reg, size, pluginID, constructCB, destructCB, copyCB)
#define rwPluginRegistryGetPluginOffset(reg, pluginID) \
       _rwPluginRegistryGetPluginOffset(reg, pluginID)
#define rwPluginRegistryInitObject(reg, object) \
       _rwPluginRegistryInitObject(reg, object)
#define rwPluginRegistryDeInitObject(reg, object) \
       _rwPluginRegistryDeInitObject(reg, object)
#define rwPluginRegistryCopyObject(reg, dstObject, srcObject) \
       _rwPluginRegistryCopyObject(reg, dstObject, srcObject)
#define rwPluginRegistryValidateObject(reg, object) \
       _rwPluginRegistryValidateObject(reg, object)


/*--- Automatically derived from: E:/nightly/rwsdk/src/batkbin.h ---*/

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Plugin binary stream stuff */
extern RwInt32 _rwPluginRegistryAddPluginStream(
                   RwPluginRegistry *reg,
                   RwUInt32 pluginID,
                   RwPluginDataChunkReadCallBack readCB,
                   RwPluginDataChunkWriteCallBack writeCB,
                   RwPluginDataChunkGetSizeCallBack getSizeCB);
extern RwInt32 _rwPluginRegistryAddPlgnStrmlwysCB(
                   RwPluginRegistry *reg,
                   RwUInt32 pluginID,
                   RwPluginDataChunkAlwaysCallBack alwaysCB);
extern const RwPluginRegistry *_rwPluginRegistryReadDataChunks(const RwPluginRegistry *reg,
                                                              RwStream *stream,
                                                              void *object);
extern const RwPluginRegistry *_rwPluginRegistryWriteDataChunks(const RwPluginRegistry *reg,
                                                               RwStream *stream,
                                                               const void *object);
extern const RwPluginRegistry *_rwPluginRegistrySkipDataChunks(const RwPluginRegistry * reg,
                                                              RwStream * stream);
extern RwInt32 _rwPluginRegistryGetSize(const RwPluginRegistry *reg, const void *object);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* Compatibility macros */

#define rwPluginRegistryAddPluginStream(reg, pluginID, readCB, writeCB, getSizeCB) \
       _rwPluginRegistryAddPluginStream(reg, pluginID, readCB, writeCB, getSizeCB)
#define rwPluginRegistryAddPluginStreamAlwaysCB(reg, pluginID, alwaysCB) \
       _rwPluginRegistryAddPlgnStrmlwysCB(reg, pluginID, alwaysCB)
#define rwPluginRegistryReadDataChunks(reg, stream, object) \
       _rwPluginRegistryReadDataChunks(reg, stream, object)
#define rwPluginRegistryWriteDataChunks(reg, stream, object) \
       _rwPluginRegistryWriteDataChunks(reg, stream, object)
#define rwPluginRegistrySkipDataChunks(reg, stream) \
       _rwPluginRegistrySkipDataChunks(reg, stream)
#define rwPluginRegistryGetSize(reg, object) \
       _rwPluginRegistryGetSize(reg, object)



/*--- Automatically derived from: E:/nightly/rwsdk/src/baraster.h ---*/

/****************************************************************************
 Defines
 */

/**
 * \ingroup datatypes
 * \ref RwRasterLockMode represents the options available for locking 
 * a raster so that it may be modified (see API function \ref RwRasterLock). An 
 * application may wish to write to the raster, read from the raster or
 * simultaneously write and read a raster (rwRASTERLOCKWRITE | rwRASTERLOCKREAD).
 */
enum RwRasterLockMode
{
    rwRASTERLOCKWRITE = 0x01,   /**<Lock for writing */
    rwRASTERLOCKREAD = 0x02,    /**<Lock for reading */
    rwRASTERLOCKNOFETCH = 0x04, /**<When used in combination with
                                 *  rwRASTERLOCKWRITE, asks the driver not to
                                 *  fetch the pixel data. This is only useful
                                 *  if it is known that ALL the raster data is
                                 *  going to be overwritten before the raster
                                 *  is unlocked, i.e. from an 
                                 *  \ref RwRasterSetFromImage call. This flag
                                 *  is not supported by all drivers. */
    rwRASTERLOCKRAW = 0x08,    /**<When used in combination with
                                   rwRASTERLOCKWRITE or rwRASTERLOCKREAD
                                   allows access to the raw platform specific
                                   pixel format */
    rwRASTERLOCKMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};

#define rwRASTERLOCKREADWRITE   (rwRASTERLOCKREAD|rwRASTERLOCKWRITE)

typedef enum RwRasterLockMode RwRasterLockMode;

/**
 * \ingroup datatypes
 *  \ref RwRasterFlipMode represents
 *  raster flip modes */
enum RwRasterFlipMode
{
    rwRASTERFLIPDONTWAIT = 0,   /**<Don't wait for VSync */
    rwRASTERFLIPWAITVSYNC = 1,  /**<Flip on VSync */
    rwRASTERFLIPMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwRasterFlipMode RwRasterFlipMode;

/**
 * \ingroup datatypes
 *  RwRasterType 
 *  This type represents the options available for creating a new 
 * raster (se API function \ref RwRasterCreate)*/
enum RwRasterType
{
    rwRASTERTYPENORMAL = 0x00,          /**<Normal */
    rwRASTERTYPEZBUFFER = 0x01,         /**<Z Buffer */
    rwRASTERTYPECAMERA = 0x02,          /**<Camera */
    rwRASTERTYPETEXTURE = 0x04,         /**<Texture */
    rwRASTERTYPECAMERATEXTURE = 0x05,   /**<Camera texture */
    rwRASTERTYPEMASK = 0x07,            /**<Mask for finding type */

    rwRASTERDONTALLOCATE = 0x80,        /**<If set the raster is not allocated */
    rwRASTERTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwRasterType RwRasterType;

/**
 * \ingroup datatypes
 * \ref RwRasterFormat is a set of values and flags which may be combined to
 * specify a raster format. The format chosen for a particular raster depends
 * on the hardware device and the raster type specified at creation time
 * (see API function \ref RwRasterCreate). The format may be retrieved using
 * API function \ref RwRasterGetFormat.
 *
 * The raster format is a packed set of bits which contains the following
 * four pieces of information (these may be combined with bitwise OR):-
 *
 * <ol>
 * <li> The pixel color format corresponding to one of the following values:-
 *      <ul>
 *      <li> rwRASTERFORMAT1555
 *      <li> rwRASTERFORMAT565
 *      <li> rwRASTERFORMAT4444
 *      <li> rwRASTERFORMATLUM8
 *      <li> rwRASTERFORMAT8888
 *      <li> rwRASTERFORMAT888
 *      <li> rwRASTERFORMAT16
 *      <li> rwRASTERFORMAT24
 *      <li> rwRASTERFORMAT32
 *      <li> rwRASTERFORMAT555
 *      </ul>
 *      This value may be masked out of the raster format using
 *      rwRASTERFORMATPIXELFORMATMASK.
 * <li> The palette depth if the raster is palettized:-
 *      <ul> 
 *      <li> rwRASTERFORMATPAL4
 *      <li> rwRASTERFORMATPAL8
 *      </ul>
 *      In these cases, the color format refers to that of the palette.
 * <li> Flag rwRASTERFORMATMIPMAP. Set if the raster contains mipmap levels.
 * <li> Flag rwRASTERFORMATAUTOMIPMAP. Set if the mipmap levels were generated
 *      automatically by RenderWare.
 * </ol>
 */
enum RwRasterFormat
{
    rwRASTERFORMATDEFAULT = 0x0000, /* Whatever the hardware likes best */

    rwRASTERFORMAT1555 = 0x0100,    /**<16 bits - 1 bit alpha, 5 bits red, green and blue */
    rwRASTERFORMAT565 = 0x0200,     /**<16 bits - 5 bits red and blue, 6 bits green */
    rwRASTERFORMAT4444 = 0x0300,    /**<16 bits - 4 bits per component */
    rwRASTERFORMATLUM8 = 0x0400,    /**<Gray scale */
    rwRASTERFORMAT8888 = 0x0500,    /**<32 bits - 8 bits per component */
    rwRASTERFORMAT888 = 0x0600,     /**<24 bits - 8 bits per component */
    rwRASTERFORMAT16 = 0x0700,      /**<16 bits - undefined: useful for things like Z buffers */
    rwRASTERFORMAT24 = 0x0800,      /**<24 bits - undefined: useful for things like Z buffers */
    rwRASTERFORMAT32 = 0x0900,      /**<32 bits - undefined: useful for things like Z buffers */
    rwRASTERFORMAT555 = 0x0a00,     /**<16 bits - 5 bits red, green and blue */

    rwRASTERFORMATAUTOMIPMAP = 0x1000, /**<RenderWare generated the mip levels */

    rwRASTERFORMATPAL8 = 0x2000,    /**<8 bit palettised */
    rwRASTERFORMATPAL4 = 0x4000,    /**<4 bit palettised */

    rwRASTERFORMATMIPMAP = 0x8000,  /**<Mip mapping on */

    rwRASTERFORMATPIXELFORMATMASK = 0x0f00, /**<The pixel color format 
                                             *  (excluding palettised bits) */
    rwRASTERFORMATMASK = 0xff00     /**<The whole format */ ,
    rwRASTERFORMATFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwRasterFormat RwRasterFormat;

enum RwRasterPrivateFlag
{
    rwRASTERGAMMACORRECTED = 0x01,
    rwRASTERPIXELLOCKEDREAD = 0x02, /* pixels are locked for reading */
    rwRASTERPIXELLOCKEDWRITE = 0x04, /* pixels are locked for writing */
    rwRASTERPALETTELOCKEDREAD = 0x08, /* palette is locked for reading */
    rwRASTERPALETTELOCKEDWRITE = 0x10, /* palette is locked for writing */
    rwRASTERPIXELLOCKEDRAW = 0x20, /* the pixels are in platform specific
                                      format, used in combination with
                                      rwRASTERPIXELLOCKEDREAD &
                                      rwRASTERPIXELLOCKEDWRITE */
    rwRASTERPRIVATEFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwRasterPrivateFlag RwRasterPrivateFlag;

#define rwRASTERPIXELLOCKED     (rwRASTERPIXELLOCKEDREAD | rwRASTERPIXELLOCKEDWRITE)
#define rwRASTERPALETTELOCKED   (rwRASTERPALETTELOCKEDREAD | rwRASTERPALETTELOCKEDWRITE)
#define rwRASTERLOCKED          (rwRASTERPIXELLOCKED|rwRASTERPALETTELOCKED)

/* How big is my stack!!! */
#define rwRASTERCONTEXTSTACKSIZE 10

/****************************************************************************
 Global Types
 */

/**
 * \ingroup datatypes
 * \typedef RwRaster 
 * Raster containing device-dependent pixels. 
 * This should be considered an opaque type.
 * Use the RwRaster API functions to access.
 */
typedef struct RwRaster RwRaster;

#if (!defined(DOXYGEN))
struct RwRaster
{
    RwRaster           *parent; /* Top level raster if a sub raster */
    RwUInt8            *cpPixels; /* Pixel pointer when locked */
    RwUInt8            *palette; /* Raster palette */
    RwInt32             width, height, depth; /* Dimensions of raster */
    RwInt32             stride; /* Lines bytes of raster */
    RwInt16             nOffsetX, nOffsetY; /* Sub raster offset */
    RwUInt8             cType;  /* Type of raster */
    RwUInt8             cFlags; /* Raster flags */
    RwUInt8             privateFlags; /* Raster private flags */
    RwUInt8             cFormat; /* Raster format */

    RwUInt8            *originalPixels;
    RwInt32             originalWidth;
    RwInt32             originalHeight;
    RwInt32             originalStride;
};
#endif /* (!defined(DOXYGEN)) */


#define RwRasterGetWidthMacro(_raster) \
    ((_raster)->width)

#define RwRasterGetHeightMacro(_raster) \
    ((_raster)->height)

#define RwRasterGetStrideMacro(_raster) \
    ((_raster)->stride)

#define RwRasterGetDepthMacro(_raster) \
    ((_raster)->depth)

#define RwRasterGetFormatMacro(_raster) \
    ((((_raster)->cFormat) & 0x000000FFL) << 8)

#define RwRasterGetParentMacro(_raster) \
    ((_raster)->parent)


/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

/* Creating destroying rasters */
extern RwRaster    *RwRasterCreate(RwInt32 width, RwInt32 height,
                                   RwInt32 depth, RwInt32 flags);
extern RwBool       RwRasterDestroy(RwRaster * raster);

/* Pulling info out of raster structure */

#if (!( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))

#define RwRasterGetWidth(_raster) RwRasterGetWidthMacro(_raster)
#define RwRasterGetHeight(_raster) RwRasterGetHeightMacro(_raster)
#define RwRasterGetStride(_raster) RwRasterGetStrideMacro(_raster)
#define RwRasterGetDepth(_raster) RwRasterGetDepthMacro(_raster)
#define RwRasterGetFormat(_raster) RwRasterGetFormatMacro(_raster)
#define RwRasterGetParent(_raster) RwRasterGetParentMacro(_raster)

#else /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */

extern RwInt32      RwRasterGetWidth(const RwRaster * raster);
extern RwInt32      RwRasterGetHeight(const RwRaster * raster);
extern RwInt32      RwRasterGetStride(const RwRaster * raster);
extern RwInt32      RwRasterGetDepth(const RwRaster * raster);
extern RwInt32      RwRasterGetFormat(const RwRaster * raster);
extern RwRaster    *RwRasterGetParent(const RwRaster * raster);


#endif /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */

extern RwRaster    *RwRasterGetOffset(RwRaster *raster, 
                                      RwInt16 *xOffset, RwInt16 *yOffset);

extern RwInt32      RwRasterGetNumLevels(RwRaster * raster);

extern RwRaster    *RwRasterSubRaster(RwRaster * subRaster,
                                      RwRaster * raster, RwRect * rect);

extern RwRaster    *RwRasterRenderFast(RwRaster * raster, RwInt32 x,
                                       RwInt32 y);
extern RwRaster    *RwRasterRender(RwRaster * raster, RwInt32 x,
                                       RwInt32 y);
extern RwRaster    *RwRasterRenderScaled(RwRaster * raster,
                                         RwRect * rect);

/* Raster rendering context */
extern RwRaster    *RwRasterPushContext(RwRaster * raster);
extern RwRaster    *RwRasterPopContext(void);
extern RwRaster    *RwRasterGetCurrentContext(void);

/* Clearing rasters */
extern RwBool       RwRasterClear(RwInt32 pixelValue);
extern RwBool       RwRasterClearRect(RwRect * rpRect,
                                          RwInt32 pixelValue);

/* Displaying rasters */
extern RwRaster    *RwRasterShowRaster(RwRaster * raster, void *dev,
                                       RwUInt32 flags);

/* Locking and releasing */
extern RwUInt8     *RwRasterLock(RwRaster * raster, RwUInt8 level,
                                 RwInt32 lockMode);
extern RwRaster    *RwRasterUnlock(RwRaster * raster);
extern RwUInt8     *RwRasterLockPalette(RwRaster * raster,
                                        RwInt32 lockMode);
extern RwRaster    *RwRasterUnlockPalette(RwRaster * raster);

/* Attaching toolkits */
extern RwInt32      RwRasterRegisterPlugin(RwInt32 size,
                                           RwUInt32 pluginID,
                                           RwPluginObjectConstructor
                                           constructCB,
                                           RwPluginObjectDestructor
                                           destructCB,
                                           RwPluginObjectCopy copyCB);
extern RwInt32      RwRasterGetPluginOffset(RwUInt32 pluginID);
extern RwBool       RwRasterValidatePlugins(const RwRaster * raster);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/bamatrix.h ---*/

/****************************************************************************
 Defines
 */

#define RWMATRIXALIGNMENT(_mat) \
   (! (((rwMATRIXALIGNMENT)-1) & ((RwUInt32)(_mat))))

#if (defined(RWMATRIXMONITOR))
# if (defined(_MSC_VER))
#  if ((_MSC_VER>=1000) && defined(_DEBUG))

typedef char        MatrixString[1024];

#define RWMATRIXPRINT(_matrix)                             \
MACRO_START                                                \
{                                                          \
    MatrixString        message;                           \
    MatrixString        output;                            \
                                                           \
    if (NULL != (_matrix))                                 \
    {                                                      \
        const RwV3d * const _x = &(_matrix)->right;        \
        const RwV3d * const _y = &(_matrix)->up;           \
        const RwV3d * const _z = &(_matrix)->at;           \
        const RwV3d * const _w = &(_matrix)->pos;          \
                                                           \
        _snprintf(message, sizeof(MatrixString),           \
                  "[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"     \
                  "  [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"     \
                  "  [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"     \
                  "  [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n"   \
                  "  %08x == flags\n"                      \
                  _x->x, _x->y, _x->z, (RwReal) 0,         \
                  _y->x, _y->y, _y->z, (RwReal) 0,         \
                  _z->x, _z->y, _z->z, (RwReal) 0,         \
                  _w->x, _w->y, _w->z, (RwReal) 1,         \
                  (_matrix)->flags);                       \
    }                                                      \
    else                                                   \
    {                                                      \
        _snprintf(message, sizeof(MatrixString),           \
                  "NULL");                                 \
    }                                                      \
                                                           \
    _snprintf(output, sizeof(MatrixString),                \
              "%s(%d): %s [%p] ==\n%s\n",                  \
              __FILE__, __LINE__,                          \
              #_matrix, _matrix, message);                 \
                                                           \
    OutputDebugString(RWSTRING(output));                   \
}                                                          \
MACRO_STOP

#  endif /* ((_MSC_VER>=1000) && defined(_DEBUG)) */
# endif /* (defined(_MSC_VER)) */
#endif /* (defined(RWMATRIXMONITOR)) */

#if (!(defined(RWMATRIXPRINT)))
#define RWMATRIXPRINT(_matrix) /* No op */
#endif /* (!(defined(RWMATRIXPRINT))) */

/**
 * \ingroup datatypes
 * enum RwOpCombineType 
 * This type represents a combination operator which 
 * can be applied to frames and matrices.
 * The operator determines the order 
 * in which one object is combined with another 
 */
enum RwOpCombineType
{
    rwCOMBINEREPLACE = 0,   /**<Replace - 
                                all previous transformations are lost */
    rwCOMBINEPRECONCAT,     /**<Pre-concatenation - 
                                the given transformation is applied 
                                before all others */
    rwCOMBINEPOSTCONCAT,    /**<Post-concatenation - 
                                the given transformation is applied 
                                after all others */
    rwOPCOMBINETYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};

/**
 * \ingroup datatypes
 * \typedef RwOpCombineType typedef for enum RwOpCombineType
 */
typedef enum RwOpCombineType RwOpCombineType;

/* External flags (bits 0-15) */

/* Internal flags (bits 16-31) */
enum RwMatrixType
{
    rwMATRIXTYPENORMAL = 0x00000001,
    rwMATRIXTYPEORTHOGANAL = 0x00000002,
    rwMATRIXTYPEORTHONORMAL = 0x00000003,
    rwMATRIXTYPEMASK = 0x00000003,
    rwMATRIXTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwMatrixType RwMatrixType;

enum RwMatrixFlag
{
    rwMATRIXINTERNALIDENTITY = 0x00020000,
    rwMATRIXFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwMatrixFlag RwMatrixFlag;

/* Flags describing what will optimize for */
enum RwMatrixOptimizations
{
    rwMATRIXOPTIMIZE_IDENTITY = 0x00020000,
    rwMATRIXOPTIMIZATIONSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwMatrixOptimizations RwMatrixOptimizations;

/****************************************************************************
 Global Types
 */

#if (!defined(DOXYGEN))
struct RwMatrix
{
    /* These are padded to be 16 byte quantities per line */
    RwV3d               right;
    RwUInt32            flags;
    RwV3d               up;
    RwUInt32            pad1;
    RwV3d               at;
    RwUInt32            pad2;
    RwV3d               pos;
    RwUInt32            pad3;
};
#endif /* (!defined(DOXYGEN)) */

/**
 * \ingroup datatypes
 * \typedef RwMatrix 
 * Matrix to define transformations. 
 * This should be considered an opaque type.
 * Use the RwMatrix API functions to access.
 */
typedef struct RwMatrix RWALIGN(RwMatrix, rwMATRIXALIGNMENT);

#if (!defined(RwMatrixCopyMacro))
#define RwMatrixCopyMacro(_target, _source)             \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwMatrixCopyMacro)) */

#if (!defined(RwMatrixSetIdentityMacro))
#define RwMatrixSetIdentityMacro(m)                                     \
MACRO_START                                                             \
{                                                                       \
    (m)->right.x = (m)->up.y    = (m)->at.z    = (RwReal)((1.0));       \
    (m)->right.y = (m)->right.z = (m)->up.x    = (RwReal)((0.0));       \
    (m)->up.z    = (m)->at.x    = (m)->at.y    = (RwReal)((0.0));       \
    (m)->pos.x   = (m)->pos.y   = (m)->pos.z   = (RwReal)((0.0));       \
    rwMatrixSetFlags((m),                                               \
                     rwMatrixGetFlags(m) |                              \
                     (rwMATRIXINTERNALIDENTITY |                        \
                      rwMATRIXTYPEORTHONORMAL));                        \
}                                                                       \
MACRO_STOP
#endif /* (!defined(RwMatrixSetIdentityMacro)) */

typedef void        (RWASMCALL * rwMatrixMultFn) (RwMatrix * dstMat,
                                                  const RwMatrix * matA,
                                                  const RwMatrix *
                                                  matB);


/****************************************************************************
 Function prototypes
 */

/* Matrix operations */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

/* Update */
#define rwMatrixSetFlags(m, flagsbit)     ((m)->flags = (flagsbit))
#define rwMatrixGetFlags(m)               ((m)->flags)
#define rwMatrixTestFlags(m, flagsbit)    ((m)->flags & (RwInt32)(flagsbit))

/* Creation/destruction */
extern RwBool
RwMatrixDestroy(RwMatrix * mpMat);

extern RwMatrix *
RwMatrixCreate(void);

#ifdef RWDEBUG

/* Functions for debug */
extern void
RwMatrixCopy(RwMatrix * dstMatrix,
             const RwMatrix * srcMatrix);

extern void
RwMatrixSetIdentity(RwMatrix * matrix);

#else                           /* RWDEBUG */

#define RwMatrixCopy(dst, src)   RwMatrixCopyMacro(dst, src)
#define RwMatrixSetIdentity(m)   RwMatrixSetIdentityMacro(m)

#endif                          /* RWDEBUG */

/* Matrix multiply */
extern RwMatrix *
RwMatrixMultiply(RwMatrix * matrixOut,
                 const RwMatrix * MatrixIn1,
                 const RwMatrix * matrixIn2);

extern RwMatrix *
RwMatrixTransform(RwMatrix * matrix,
                  const RwMatrix * transform,
                  RwOpCombineType combineOp);

/* Normalise */
extern RwMatrix *
RwMatrixOrthoNormalize(RwMatrix * matrixOut,
                       const RwMatrix * matrixIn);

/* Inversion */
extern RwMatrix *
RwMatrixInvert(RwMatrix * matrixOut,
               const RwMatrix * matrixIn);

/* Unary matrix operations */
extern RwMatrix *
RwMatrixScale(RwMatrix * matrix,
              const RwV3d * scale,
              RwOpCombineType combineOp);

extern RwMatrix *
RwMatrixTranslate(RwMatrix * matrix,
                  const RwV3d * translation,
                  RwOpCombineType combineOp);

extern RwMatrix *
RwMatrixRotate(RwMatrix * matrix,
               const RwV3d * axis,
               RwReal angle,
               RwOpCombineType combineOp);

extern RwMatrix *
RwMatrixRotateOneMinusCosineSine(RwMatrix * matrix,
                                 const RwV3d *unitAxis,
                                 RwReal oneMinusCosine,
                                 RwReal sine,
                                 RwOpCombineType combineOp);

/* Query what the matrix is */
extern const RwMatrix *
RwMatrixQueryRotate(const RwMatrix * matrix,
                    RwV3d * unitAxis,
                    RwReal * angle,
                    RwV3d * center);

/* Get components */
#ifndef RWDEBUG

#define RwMatrixGetRight(m)    (&(m)->right)
#define RwMatrixGetUp(m)       (&(m)->up)
#define RwMatrixGetAt(m)       (&(m)->at)
#define RwMatrixGetPos(m)      (&(m)->pos)

#else                           /* RWDEBUG */

extern RwV3d *
RwMatrixGetRight(RwMatrix * matrix);

extern RwV3d *
RwMatrixGetUp(RwMatrix * matrix);

extern RwV3d *
RwMatrixGetAt(RwMatrix * matrix);

extern RwV3d *
RwMatrixGetPos(RwMatrix * matrix);

#endif                          /* RWDEBUG */

/* Update the internal matrix state wrt its elements */
extern RwMatrix *
RwMatrixUpdate(RwMatrix * matrix);

/* Update the internal matrix flags wrt its elements */
extern RwMatrix *
RwMatrixOptimize(RwMatrix *matrix, RwReal tolerance);

extern RwReal
_rwMatrixDeterminant(const RwMatrix * matrix);

extern RwReal
_rwMatrixNormalError(const RwMatrix * matrix);

extern RwReal
_rwMatrixOrthogonalError(const RwMatrix * matrix);

extern RwReal
_rwMatrixIdentityError(const RwMatrix * matrix);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* Compatibility macros */

#define rwMatrixSetOptimizations(optimizeFlags) \
       _rwMatrixSetOptimizations(optimizeFlags)

#define rwMatrixSetMultFn(multMat) \
       _rwMatrixSetMultFn(multMat)

#define rwMatrixOpen(instance, offset, size) \
       _rwMatrixOpen(instance, offset, size)

#define rwMatrixClose(instance, offset, size) \
       _rwMatrixClose(instance, offset, size)

/* Initialisation/deinitialisation */
#define rwMatrixInitialize(m, t)                \
MACRO_START                                     \
{                                               \
    rwMatrixSetFlags((m), (t));                 \
}                                               \
MACRO_STOP

#define RWMATRIXOPTIMIZETOLERANCE  (((RwReal)1)/((RwReal)(1<<8)))

#define rwMatrixIsOrthonormal(_matrix, _epsilon)        \
  ( ( (_epsilon) >= _rwMatrixNormalError(_matrix) ) &&   \
( (_epsilon) >= _rwMatrixOrthogonalError(_matrix) ) )

#define rwMatrixIsOrthonormalPositive(_matrix, _epsilon)                \
  ( rwMatrixIsOrthonormal(_matrix, _epsilon) &&                         \
( (((RwReal)1) - (_epsilon)) <= _rwMatrixDeterminant(_matrix) ) )

#define rwMatrixIsIdentity(_matrix, _epsilon)           \
   ( (_epsilon) >= _rwMatrixIdentityError(_matrix) )

#define rwMatrixValidFlags(_matrix, _epsilon)                           \
   ( (_matrix) &&                          /* valid pointer */          \
 ( ( !( rwMatrixGetFlags(_matrix) &    /* not flagged as identity */    \
        rwMATRIXINTERNALIDENTITY) ) || /* .. or actually is */          \
   rwMatrixIsIdentity(_matrix, _epsilon)) &&                            \
 ( ( !( rwMatrixGetFlags(_matrix) &    /* not flagged as rigid */       \
        rwMATRIXTYPEORTHONORMAL) ) ||  /* ... or actually is */         \
   rwMatrixIsOrthonormalPositive(_matrix, _epsilon)) )

#define      rwMat01Det(_mAA)                                           \
  ( (_mAA) )

#define      rwMat02Det(_mAA, _mAB,                                     \
                        _mBA, _mBB)                                     \
  ( (_mAA) * rwMat01Det(_mBB)                                           \
  - (_mAB) * rwMat01Det(_mBA)                                           \
  )

#define      rwMat03Det(_mAA, _mAB, _mAC,                               \
                        _mBA, _mBB, _mBC,                               \
                        _mCA, _mCB, _mCC)                               \
  ( (_mAA) * rwMat02Det(_mBB, _mBC,                                     \
                        _mCB, _mCC)                                     \
  - (_mAB) * rwMat02Det(_mBA, _mBC,                                     \
                        _mCA, _mCC)                                     \
  + (_mAC) * rwMat02Det(_mBA, _mBB,                                     \
                        _mCA, _mCB)                                     \
  )

#define      rwMat04Det(_mAA, _mAB, _mAC, _mAD,                         \
                        _mBA, _mBB, _mBC, _mBD,                         \
                        _mCA, _mCB, _mCC, _mCD,                         \
                        _mDA, _mDB, _mDC, _mDD)                         \
  ( (_mAA) * rwMat03Det(_mBB, _mBC, _mBD,                               \
                        _mCB, _mCC, _mCD,                               \
                        _mDB, _mDC, _mDD)                               \
  - (_mAB) * rwMat03Det(_mBA, _mBC, _mBD,                               \
                        _mCA, _mCC, _mCD,                               \
                        _mDA, _mDC, _mDD)                               \
  + (_mAC) * rwMat03Det(_mBA, _mBB, _mBD,                               \
                        _mCA, _mCB, _mCD,                               \
                        _mDA, _mDB, _mDD)                               \
  - (_mAD) * rwMat03Det(_mBA, _mBB, _mBC,                               \
                        _mCA, _mCB, _mCC,                               \
                        _mDA, _mDB, _mDC)                               \
  )

#define rwMat02Inv(_rAA, _rAB,                                          \
                   _rBA, _rBB)                                          \
                   _mAA, _mAB,                                          \
                   _mBA, _mBB)                                          \
MACRO_START                                                             \
{                                                                       \
    RwReal factor;                                                      \
                                                                        \
    (_rAA) =  rwMat01Det(_mBB);                                         \
    (_rAB) = -rwMat01Det(_mAB);                                         \
                                                                        \
    factor = ( (_rAA) * (_mAA) +                                        \
               (_rAB) * (_mBA) );                                       \
                                                                        \
    factor = ( (factor != 0)?                                           \
               (((RwReal)1)/factor):                                    \
               ((RwReal)1) );                                           \
                                                                        \
    (_rAA) *= factor;                                                   \
    (_rAB) *= factor;                                                   \
                                                                        \
    (_rBA) = -rwMat01Det(_mBA) * factor;                                \
    (_rBB) =  rwMat01Det(_mAA) * factor;                                \
}                                                                       \
MACRO_STOP

#define    rwMat03Inv(_rAA, _rAB, _rAC,                                 \
                      _rBA, _rBB, _rBC,                                 \
                      _rCA, _rCB, _rCC,                                 \
                      _mAA, _mAB, _mAC,                                 \
                      _mBA, _mBB, _mBC,                                 \
                      _mCA, _mCB, _mCC)                                 \
MACRO_START                                                             \
{                                                                       \
    RwReal factor;                                                      \
                                                                        \
    (_rAA)=  rwMat02Det(_mBB, _mBC,                                     \
                        _mCB, _mCC);                                    \
    (_rAB)= -rwMat02Det(_mAB, _mAC,                                     \
                        _mCB, _mCC);                                    \
    (_rAC)=  rwMat02Det(_mAB, _mAC,                                     \
                        _mBB, _mBC);                                    \
    factor = ( (_rAA) * (_mAA) +                                        \
               (_rAB) * (_mBA) +                                        \
               (_rAC) * (_mCA) );                                       \
                                                                        \
    factor = ( (factor != 0)?                                           \
               (((RwReal)1)/factor):                                    \
               ((RwReal)1) );                                           \
                                                                        \
    (_rAA) *= factor;                                                   \
    (_rAB) *= factor;                                                   \
    (_rAC) *= factor;                                                   \
    (_rBA)= -rwMat02Det(_mBA, _mBC,                                     \
                        _mCA, _mCC) * factor ;                          \
    (_rBB)=  rwMat02Det(_mAA, _mAC,                                     \
                        _mCA, _mCC) * factor ;                          \
    (_rBC)= -rwMat02Det(_mAA, _mAC,                                     \
                        _mBA, _mBC) * factor ;                          \
    (_rCA)=  rwMat02Det(_mBA, _mBB,                                     \
                        _mCA, _mCB) * factor ;                          \
    (_rCB)= -rwMat02Det(_mAA, _mAB,                                     \
                        _mCA, _mCB) * factor ;                          \
    (_rCC)=  rwMat02Det(_mAA, _mAB,                                     \
                        _mBA, _mBB) * factor ;                          \
}                                                                       \
MACRO_STOP

#define    rwMat04Inv(_rAA, _rAB, _rAC, _rAD,                           \
                      _rBA, _rBB, _rBC, _rBD,                           \
                      _rCA, _rCB, _rCC, _rCD,                           \
                      _rDA, _rDB, _rDC, _rDD,                           \
                      _mAA, _mAB, _mAC, _mAD,                           \
                      _mBA, _mBB, _mBC, _mBD,                           \
                      _mCA, _mCB, _mCC, _mCD,                           \
                      _mDA, _mDB, _mDC, _mDD)                           \
MACRO_START                                                             \
{                                                                       \
    RwReal factor;                                                      \
                                                                        \
    (_rAA)=  rwMat03Det(_mBB, _mBC, _mBD,                               \
                        _mCB, _mCC, _mCD,                               \
                        _mDB, _mDC, _mDD);                              \
    (_rAB)= -rwMat03Det(_mAB, _mAC, _mAD,                               \
                        _mCB, _mCC, _mCD,                               \
                        _mDB, _mDC, _mDD);                              \
    (_rAC)=  rwMat03Det(_mAB, _mAC, _mAD,                               \
                        _mBB, _mBC, _mBD,                               \
                        _mDB, _mDC, _mDD);                              \
    (_rAD)= -rwMat03Det(_mAB, _mAC, _mAD,                               \
                        _mBB, _mBC, _mBD,                               \
                        _mCB, _mCC, _mCD);                              \
    factor = ( (_rAA) * (_mAA) +                                        \
               (_rAB) * (_mBA) +                                        \
               (_rAC) * (_mCA) +                                        \
               (_rAD) * (_mDA) );                                       \
                                                                        \
    factor = ( (factor != 0)?                                           \
               (((RwReal)1)/factor):                                    \
               ((RwReal)1) );                                           \
                                                                        \
    (_rAA) *= factor;                                                   \
    (_rAB) *= factor;                                                   \
    (_rAC) *= factor;                                                   \
    (_rAD) *= factor;                                                   \
    (_rBA)= -rwMat03Det(_mBA, _mBC, _mBD,                               \
                        _mCA, _mCC, _mCD,                               \
                        _mDA, _mDC, _mDD) * factor ;                    \
    (_rBB)=  rwMat03Det(_mAA, _mAC, _mAD,                               \
                        _mCA, _mCC, _mCD,                               \
                        _mDA, _mDC, _mDD) * factor ;                    \
    (_rBC)= -rwMat03Det(_mAA, _mAC, _mAD,                               \
                        _mBA, _mBC, _mBD,                               \
                        _mDA, _mDC, _mDD) * factor ;                    \
    (_rBD)=  rwMat03Det(_mAA, _mAC, _mAD,                               \
                        _mBA, _mBC, _mBD,                               \
                        _mCA, _mCC, _mCD) * factor ;                    \
    (_rCA)=  rwMat03Det(_mBA, _mBB, _mBD,                               \
                        _mCA, _mCB, _mCD,                               \
                        _mDA, _mDB, _mDD) * factor ;                    \
    (_rCB)= -rwMat03Det(_mAA, _mAB, _mAD,                               \
                        _mCA, _mCB, _mCD,                               \
                        _mDA, _mDB, _mDD) * factor ;                    \
    (_rCC)=  rwMat03Det(_mAA, _mAB, _mAD,                               \
                        _mBA, _mBB, _mBD,                               \
                        _mDA, _mDB, _mDD) * factor ;                    \
    (_rCD)= -rwMat03Det(_mAA, _mAB, _mAD,                               \
                        _mBA, _mBB, _mBD,                               \
                        _mCA, _mCB, _mCD) * factor ;                    \
    (_rDA)= -rwMat03Det(_mBA, _mBB, _mBC,                               \
                        _mCA, _mCB, _mCC,                               \
                        _mDA, _mDB, _mDC) * factor ;                    \
    (_rDB)=  rwMat03Det(_mAA, _mAB, _mAC,                               \
                        _mCA, _mCB, _mCC,                               \
                        _mDA, _mDB, _mDC) * factor ;                    \
    (_rDC)= -rwMat03Det(_mAA, _mAB, _mAC,                               \
                        _mBA, _mBB, _mBC,                               \
                        _mDA, _mDB, _mDC) * factor ;                    \
    (_rDD)=  rwMat03Det(_mAA, _mAB, _mAC,                               \
                        _mBA, _mBB, _mBC,                               \
                        _mCA, _mCB, _mCC) * factor ;                    \
}                                                                       \
MACRO_STOP


/*--- Automatically derived from: E:/nightly/rwsdk/src/balist.h ---*/
/****************************************************************************
 Global Types
 */

typedef struct RwSList RwSList;
struct RwSList
{
    RwUInt8    *listElements;
    RwInt32     numElementsFilled;
    RwInt32     numElementsAlloced;
    RwInt32     entrySize;
};



/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* SList functions */
extern RwSList    *_rwSListCreate(RwInt32 size);
extern RwBool      _rwSListDestroy(RwSList *sList);
extern RwBool      _rwSListDestroyArray(RwUInt8 *array);
extern void         _rwSListDestroyEndEntries(RwSList *sList, RwInt32 amount);
extern RwBool      _rwSListDestroyEntry(RwSList *sList, RwInt32 entry);
extern void         _rwSListEmpty(RwSList *sList);
extern void        *_rwSListGetArray(RwSList *sList);
extern void        *_rwSListGetEntry(RwSList *sList, RwInt32 entry);
extern void        *_rwSListGetNewEntry(RwSList *sList);
extern void        *_rwSListGetNewEntries(RwSList *sList, RwInt32 entry);
extern RwInt32     _rwSListGetNumEntries(const RwSList *sList);
extern RwBool      _rwSListReleaseArray(RwSList *sList);
extern void        *_rwSListToArray(RwSList *sList);


#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* Comparibility macros */

#define rwSListCreate(size) \
       _rwSListCreate(size)
#define rwSListDestroy(sList) \
       _rwSListDestroy(sList)
#define rwSListDestroyArray(array) \
       _rwSListDestroyArray(array)
#define rwSListDestroyEndEntries(sList, amount) \
       _rwSListDestroyEndEntries(sList, amount)
#define rwSListDestroyEntry(sList, entry) \
       _rwSListDestroyEntry(sList, entry)
#define rwSListEmpty(sList) \
       _rwSListEmpty(sList)
#define rwSListGetArray(sList) \
       _rwSListGetArray(sList)
#define rwSListGetEntry(sList, entry) \
       _rwSListGetEntry(sList, entry)
#define rwSListGetNewEntry(sList) \
       _rwSListGetNewEntry(sList)
#define rwSListGetNewEntries(sList, entry) \
       _rwSListGetNewEntries(sList, entry)
#define rwSListGetNumEntries(sList) \
       _rwSListGetNumEntries(sList)
#define rwSListReleaseArray(sList) \
       _rwSListReleaseArray(sList)
#define rwSListToArray(sList) \
       _rwSListToArray(sList)


/*--- Automatically derived from: E:/nightly/rwsdk/src/bafsys.h ---*/

/****************************************************************************
 Global Types
 */

/*
 * \typedef rwFnFexist
 * Returns true if file with given name exists, false if it doesn't.
 */
typedef RwBool  (*rwFnFexist)(const RwChar *name);

/*
 * \typedef rwFnFopen
 * Mimics ANSI C Standard Library fopen.
 */
typedef void   *(*rwFnFopen)(const RwChar *name, const RwChar *access);

/*
 * \typedef rwFnFclose
 * Mimics ANSI C Standard Library fclose.
 */
typedef int     (*rwFnFclose)(void *fptr);

/*
 * \typedef rwFnFread
 * Mimics ANSI C Standard Library fread.
 */
typedef size_t  (*rwFnFread)(void *addr, size_t size, size_t count, void *fptr);

/*
 * \typedef rwFnFwrite
 * Mimics ANSI C Standard Library fwrite.
 */
typedef size_t  (*rwFnFwrite)(const void *addr, size_t size, size_t count, void *fptr);

/*
 * \typedef rwFnFgets
 * Mimics ANSI C Standard Library fgets.
 */
typedef RwChar *(*rwFnFgets)(RwChar *buffer, int maxLen, void *fptr);

/*
 * \typedef rwFnFputs
 * Mimics ANSI C Standard Library fputs.
 */
typedef int     (*rwFnFputs)(const RwChar *buffer, void *fptr);

/*
 * \typedef rwFnFeof
 * Mimics ANSI C Standard Library feof.
 */
typedef int     (*rwFnFeof)(void *fptr);

/*
 * \typedef rwFnFseek
 * Mimics ANSI C Standard Library fseek.
 */
typedef int     (*rwFnFseek)(void *fptr, long offset, int origin);

/*
 * \typedef rwFnFflush
 * Mimics ANSI C Standard Library fflush.
 */
typedef int     (*rwFnFflush)(void *fptr);

/*
 * \typedef rwFnFtell
 * Mimics ANSI C Standard Library ftell.
 */
typedef int     (*rwFnFtell)(void *fptr);


/**
 * \ingroup datatypes
 * \typedef RwFileFunctions
 * typedef for struct RwFileFunctions
 */
typedef struct RwFileFunctions RwFileFunctions;
/**
 * \ingroup datatypes
 * \struct RwFileFunctions
 * This type is used to specify the file access
 * functions used by RenderWare. The default file system uses the standard
 * ANSI functions. The application may install an alternative file system
 * providing it complies with the ANSI interface -- see API 
 * function \ref RwOsGetFileInterface.
 *
 * The function types associated with this type are defined as follows 
 *
 * \verbatim
   RwBool (*rwFnFexist)(const RwChar *name)
       void *(*rwFnFopen)(const RwChar *name, const RwChar *access) 
       int (*rwFnFclose)(void *fptr)
       size_t (*rwFnFread)(void *addr, size_t size, size_t count, void *fptr)                        
       size_t (*rwFnFwrite)(const void *addr, size_t size, size_t count,
                 void *fptr)
   RwChar *(*rwFnFgets)(RwChar *buffer, int maxLen, void *fptr)
       int (*rwFnFputs)(const RwChar *buffer, void *fptr)
       int (*rwFnFeof)(void *fptr)
       int (*rwFnFseek)(void *fptr, long offset, int origin)
       int (*rwFnFflush)(void *fptr)
       int (*rwFnFtell)(void *fptr)
 \endverbatim
 * Note the function argument lists are consistent with the ANSI
 * standard file access interface:
 */
struct RwFileFunctions
{
    rwFnFexist  rwfexist; /**< Pointer to fexist function */
    rwFnFopen   rwfopen;  /**< Pointer to fopen function */
    rwFnFclose  rwfclose; /**< Pointer to fclose function */
    rwFnFread   rwfread;  /**< Pointer to fread function */
    rwFnFwrite  rwfwrite; /**< Pointer to fwrite function */
    rwFnFgets   rwfgets;  /**< Pointer to fgets function */
    rwFnFputs   rwfputs;  /**< Pointer to puts function */
    rwFnFeof    rwfeof;   /**< Pointer to feof function */
    rwFnFseek   rwfseek;  /**< Pointer to fseek function */
    rwFnFflush  rwfflush; /**< Pointer to fflush function */
    rwFnFtell   rwftell;  /**< Pointer to ftell function */  
};


#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

extern RwFileFunctions *RwOsGetFileInterface(void);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/baframe.h ---*/

/****************************************************************************
 Defines
 */

#if (!defined(RWFRAMESTATICPLUGINSSIZE))
#define RWFRAMESTATICPLUGINSSIZE 0
#endif

#define RWFRAMEALIGNMENT(_frame) \
   (! (((rwFRAMEALIGNMENT)-1) & ((RwUInt32)(_frame))))

/* Type ID */
#define rwFRAME 0

/* dirty flag bits */
#define rwFRAMEPRIVATEHIERARCHYSYNCLTM  0x01
#define rwFRAMEPRIVATEHIERARCHYSYNCOBJ  0x02
#define rwFRAMEPRIVATESUBTREESYNCLTM    0x04
#define rwFRAMEPRIVATESUBTREESYNCOBJ    0x08
#define rwFRAMEPRIVATESTATIC            0x10

/****************************************************************************
 Global Types
 */

#if (!defined(DOXYGEN))
struct RwFrame
{
    RwObject            object;

    /* Put embedded matrics here to ensure they remain 16-byte aligned */
    RwMatrix            modelling;
    RwMatrix            ltm;

    RwLLLink            inDirtyListLink;

    RwLinkList          objectList; /* List of objects connected to a frame */

    struct RwFrame      *child;
    struct RwFrame      *next;
    struct RwFrame      *root;   /* Root of the tree */

#if (RWFRAMESTATICPLUGINSSIZE)
    RWALIGN(RwUInt8             pluginData[RWFRAMESTATICPLUGINSSIZE], rwFRAMEALIGNMENT);
#endif /* defined(RWFRAMESTATICPLUGINSIZE)) */
};
#endif /* (!defined(DOXYGEN)) */

/**
 * \ingroup datatypes
 * \typedef RwFrame 
   Frame for defining object position and orientation. 
 * This should be considered an opaque type.
 * Use the RwFrame API functions to access.
 */
typedef struct RwFrame RWALIGN(RwFrame, rwFRAMEALIGNMENT);

/**
 * \ingroup datatypes
 * \typedef RwFrameCallBack
 * \ref RwFrameCallBack type represents the function 
 * called from \ref RwFrameForAllChildren for all child frames linked to a given frame.  
 * This function should return a pointer to the current frame to indicate success.  
 * The callback may return NULL to terminate further callbacks on the child frames.
 * 
 * \param  frame   Pointer to the current frame, supplied by
 * iterator.
 * \param  data  Pointer to developer-defined data structure.
 *
 * \see RwFrameForAllChildren
 *
 */
typedef RwFrame *(*RwFrameCallBack)(RwFrame *frame, void *data);


#define RwFrameGetParentMacro(_f)   ((RwFrame *)rwObjectGetParent(_f))
#if (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))
#define RwFrameGetParent(_f)    RwFrameGetParentMacro(_f)
#endif

#define RwFrameGetMatrixMacro(_f)   (&(_f)->modelling)
#if (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))
#define RwFrameGetMatrix(_f)    RwFrameGetMatrixMacro(_f)
#endif



/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

/* Finding what is attached to a frame */
extern RwFrame *
RwFrameForAllObjects(RwFrame * frame,
                     RwObjectCallBack callBack,
                     void *data);

/* Matrix operations */
extern RwFrame *
RwFrameTranslate(RwFrame * frame,
                 const RwV3d * v,
                 RwOpCombineType combine);

extern RwFrame *
RwFrameRotate(RwFrame * frame,
              const RwV3d * axis,
              RwReal angle,
              RwOpCombineType combine);

extern RwFrame *
RwFrameScale(RwFrame * frame,
             const RwV3d * v,
             RwOpCombineType combine);

extern RwFrame *
RwFrameTransform(RwFrame * frame,
                 const RwMatrix * m,
                 RwOpCombineType combine);

extern RwFrame *
RwFrameOrthoNormalize(RwFrame * frame);

extern RwFrame *
RwFrameSetIdentity(RwFrame * frame);

/* Cloning */
extern RwFrame *
RwFrameCloneHierarchy(RwFrame * root);

/* Destruction */
extern RwBool
RwFrameDestroyHierarchy(RwFrame * frame);

/* Building a frame */
extern RwFrame *
RwFrameForAllChildren(RwFrame * frame,
                      RwFrameCallBack callBack,
                      void *data);

extern RwFrame *
RwFrameRemoveChild(RwFrame * child);

extern RwFrame *
RwFrameAddChild(RwFrame * parent,
                RwFrame * child);

#if ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )
extern RwFrame *
RwFrameGetParent(const RwFrame * frame);
#endif

/* Getting the root */
extern RwFrame *
RwFrameGetRoot(const RwFrame * frame);

/* Getting Matrices */
extern RwMatrix *
RwFrameGetLTM(RwFrame * frame);

#if ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )
extern RwMatrix *
RwFrameGetMatrix(RwFrame * frame);
#endif

/* Elements */
extern RwFrame *
RwFrameUpdateObjects(RwFrame * frame);

/* Creating destroying frames */
extern RwFrame *
RwFrameCreate(void);

extern RwBool
RwFrameInit(RwFrame *frame);

extern RwBool
RwFrameDeInit(RwFrame *frame);

extern RwBool
RwFrameDestroy(RwFrame * frame);

/* internal function used by Create and Init */
extern void
_rwFrameInit(RwFrame *frame);

/* internal function used by Destroy and DeInit */
extern void
_rwFrameDeInit(RwFrame *frame);

/* Finding a frames state */
extern RwBool
RwFrameDirty(const RwFrame * frame);

/* Find the amount of frames in a hierarchy */
extern RwInt32
RwFrameCount(RwFrame * frame);

/* Plugins */
extern RwBool
RwFrameSetStaticPluginsSize(RwInt32 size);

extern RwInt32
RwFrameRegisterPlugin(RwInt32 size,
                      RwUInt32 pluginID,
                      RwPluginObjectConstructor constructCB,
                      RwPluginObjectDestructor destructCB,
                      RwPluginObjectCopy copyCB);

extern RwInt32
RwFrameGetPluginOffset(RwUInt32 pluginID);

extern RwBool
RwFrameValidatePlugins(const RwFrame * frame);

/* Cloning */
extern RwFrame *
_rwFrameCloneAndLinkClones(RwFrame * root);

extern
RwFrame *
_rwFramePurgeClone(RwFrame *root);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* Compatibility macros */

#define rwFrameGetParent(frame) \
       _rwFrameGetParent(frame)

#define rwFrameInit(frame) \
       _rwFrameInit(frame)

#define rwFrameDeInit(frame) \
       _rwFrameDeInit(frame)

#define rwFrameCloneAndLinkClones(root) \
       _rwFrameCloneAndLinkClones(root)

#define rwFramePurgeClone(root) \
       _rwFramePurgeClone(root)

#define rwFrameClose(instance, offset, size) \
       _rwFrameClose(instance, offset, size)

#define rwFrameOpen(instance, offset, size) \
       _rwFrameOpen(instance, offset, size)


/*--- Automatically derived from: E:/nightly/rwsdk/src/batypehf.h ---*/

typedef struct RwObjectHasFrame RwObjectHasFrame;
typedef RwObjectHasFrame * (*RwObjectHasFrameSyncFunction)(RwObjectHasFrame *object);
struct RwObjectHasFrame
{
    RwObject                     object;
    RwLLLink                     lFrame;
    RwObjectHasFrameSyncFunction sync;
};

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Frames */
extern void _rwObjectHasFrameSetFrame(void *object, RwFrame *frame);
extern void _rwObjectHasFrameReleaseFrame(void *object);

/* ObjectHASFRAME METHODS */
#define rwObjectHasFrameInitialize(o, type, subtype, syncFunc)  \
MACRO_START                                                     \
{                                                               \
    rwObjectInitialize(o, type, subtype);                       \
    ((RwObjectHasFrame *)o)->sync = syncFunc;                   \
}                                                               \
MACRO_STOP

#define rwObjectHasFrameSync(o) \
    ((RwObjectHasFrame *)(o))->sync(o)

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* Compatibility macros */

#define rwObjectHasFrameSetFrame(object, frame) \
        _rwObjectHasFrameSetFrame(object, frame)
#define rwObjectHasFrameReleaseFrame(object) \
        _rwObjectHasFrameReleaseFrame(object)



/*--- Automatically derived from: E:/nightly/rwsdk/src/basync.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/baerr.h ---*/
/****************************************************************************
 Global Types
 */

typedef struct RwError RwError;
/**
 * \ingroup datatypes
 * \struct RwError
 * This type represents a RenderWare error specified by the
 * ID of the plugin that the error was issued from (pluginID) and the error
 * code itself (errorCode) (see API function \ref RwErrorGet).
 * \param pluginID The ID of the plugin that issued the error.
 * \param errorCode A value representing the error code.
 */
struct RwError
{
    RwInt32     pluginID;  /**< Internal Use */
    RwInt32     errorCode; /**< Internal Use */
};

#define RWECODE(a,b) a,

/* common errors have the MSB set */

enum RwErrorCodeCommon
{
    E_RW_NOERROR = (int)0x80000000L,
#include "errcom.def"
    E_RW_LASTERROR = RWFORCEENUMSIZEINT
};
typedef enum RwErrorCodeCommon RwErrorCodeCommon;

#undef RWECODE

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

extern RwError *RwErrorGet(RwError *code);
extern RwError *RwErrorSet(RwError *code);
extern RwInt32 _rwerror(RwInt32 code, ...);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/badebug.h ---*/

/****************************************************************************
 Global Types
 */

/**
 * \ingroup datatypes
 * RwDebugType 
 * This type represents the different types of debug and 
 * trace messages that can be sent to the currently installed debug handler 
 * (see API function \ref RwDebugSendMessage)*/
enum RwDebugType
{
    rwNADEBUGTYPE = 0,          /**<Invalid */
    rwDEBUGASSERT,              /**<Send an assert message */
    rwDEBUGERROR,               /**<Send an error message */
    rwDEBUGMESSAGE,             /**<Send an informational message */
    rwDEBUGTRACE,               /**<Send a trace message */
    rwDEBUGTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwDebugType RwDebugType;

/**
 * \ingroup datatypes
 * \ref RwDebugHandler
 * This type represents the
 * function called from \ref RwDebugSendMessage for sending a message to the
 * RenderWare debug stream.
 *
 * \param  type   Type of debug message (assert, error, etc.).
 *
 * \param  string   Pointer to a string containing the error
 * message.
 *
 * \see RwDebugSetHandler
 */
typedef void        (*RwDebugHandler) (RwDebugType type,

                                       const RwChar * string);

#ifdef RWDEBUG

#define RwDebugSendMessage(type, funcName, message)     \
        _rwDebugSendMessage(type,                       \
                            RWSTRING(__FILE__),         \
                            __LINE__,                   \
                            funcName,                   \
                            message)

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

/* Setting the debug message handler */
extern RwDebugHandler RwDebugSetHandler(RwDebugHandler handler);
extern void         RwDebugSetTraceState(RwBool state);

extern void         _rwDebugSendMessage(RwDebugType type,
                                        const RwChar * file,
                                        const RwInt32 line,
                                        const RwChar * funcName,
                                        const RwChar * message);

/* Sending a message */
extern RwChar      *_rwdberrcommon(RwInt32 code, ...);
extern RwChar      *_rwdbsprintf(const RwChar * format,
                                 ...) __RWFORMAT__(printf, 1, 2);


#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

#else /* RWDEBUG */

#define RwDebugSetHandler(handler)
#define RwDebugSetTraceState(state)
#define RwDebugSendMessage(type, funcName, message)

#if (!defined(RWREGSETDEBUGTRACE))
#define RWREGSETDEBUGTRACE(_name) /* No op */
#endif /* (!defined(RWREGSETDEBUGTRACE)) */

#endif /* RWDEBUG */


/*--- Automatically derived from: E:/nightly/rwsdk/src/bacolor.h ---*/
/****************************************************************************
 Global Types
 */

typedef struct RwRGBAReal RwRGBAReal;
/**
 * \ingroup datatypes
 * \struct RwRGBAReal
 * This structure represents a RGBA color which has 
 * components specified as real values. 
 *
 * A color component of an RwRGBA with the value 255 generally corresponds 
 * to the associated component in an RwRGBAReal with the value 1.0f. 
 * However, any values can be substituted to denormalize/normalize 
 * RwRGBAReal and create different effects. For example, while light colors
 * are expressed as normalized RGBA, interesting effects can be gained using 
 * larger values. 
 *
 * It should also be noted that a color component of an RwRGBA with the 
 * value 0 generally corresponds to the associcated component in an 
 * RwRGBAReal with the value 0.0.
 */
struct RwRGBAReal
{
    RwReal red;     /**< red component */
    RwReal green;   /**< green component */
    RwReal blue;    /**< blue component */
    RwReal alpha;   /**< alpha component */
};

#if (!defined(RwRGBARealAssign))
#define RwRGBARealAssign(_target, _source)        \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwRGBARealAssign)) */

typedef struct RwRGBA RwRGBA;
/**
 * \ingroup datatypes
 * \struct RwRGBA
 * This structure represents a RGBA color 
 * which has integer components specified in the range 0 to 255. */
struct RwRGBA
{
    RwUInt8 red;    /**< red component */
    RwUInt8 green;  /**< green component */
    RwUInt8 blue;   /**< blue component */
    RwUInt8 alpha;  /**< alpha component */
};

#if (!defined(RwRGBAAssign))
#define RwRGBAAssign(_target, _source)             \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwRGBAAssign)) */

#define RwRGBARealAddMacro(o,a,b)                                        \
MACRO_START                                                              \
{                                                                        \
    (o)->red   = (((a)->red) + (   (b)->red));                           \
    (o)->green = (((a)->green) + ( (b)->green));                         \
    (o)->blue  = (((a)->blue) + (  (b)->blue));                          \
    (o)->alpha = (((a)->alpha) + ( (b)->alpha));                         \
}                                                                        \
MACRO_STOP

#define RwRGBARealSubMacro(o,a,b)                                        \
MACRO_START                                                              \
{                                                                        \
    (o)->red   = (((a)->red) - (   (b)->red));                           \
    (o)->green = (((a)->green) - ( (b)->green));                         \
    (o)->blue  = (((a)->blue) - (  (b)->blue));                          \
    (o)->alpha = (((a)->alpha) - ( (b)->alpha));                         \
}                                                                        \
MACRO_STOP

#define RwRGBARealScaleMacro(o,a,scale)                                  \
MACRO_START                                                              \
{                                                                        \
    (o)->red   = (((a)->red) * (   scale));                              \
    (o)->green = (((a)->green) * ( scale));                              \
    (o)->blue  = (((a)->blue) * (  scale));                              \
    (o)->alpha = (((a)->alpha) * ( scale));                              \
}                                                                        \
MACRO_STOP

/* Conversion macros */
#define RwRGBAFromRwRGBARealMacro(o, i)                                  \
MACRO_START                                                              \
{                                                                        \
    RwInt32 quantize;                                                    \
                                                                         \
    quantize = (RwInt32)                                                 \
        ( ((i)->red   * (RwReal)255.0) + (RwReal)0.5 );                  \
    (o)->red   = (RwUInt8) quantize;                                     \
    quantize = (RwInt32)                                                 \
        ( ((i)->green * (RwReal)255.0) + (RwReal)0.5 );                  \
    (o)->green = (RwUInt8) quantize;                                     \
    quantize = (RwInt32)                                                 \
        ( ((i)->blue  * (RwReal)255.0) + (RwReal)0.5 );                  \
    (o)->blue  = (RwUInt8) quantize;                                     \
    quantize = (RwInt32)                                                 \
        ( ((i)->alpha * (RwReal)255.0) + (RwReal)0.5 );                  \
    (o)->alpha = (RwUInt8) quantize;                                     \
                                                                         \
}                                                                        \
MACRO_STOP

#define RwRGBARealFromRwRGBAMacro(o, i)                                  \
MACRO_START                                                              \
{                                                                        \
    (o)->red   =                                                         \
        (((RwReal)(((i)->red))) * (   (RwReal)((1.0/255.0))));           \
    (o)->green =                                                         \
        (((RwReal)(((i)->green))) * ( (RwReal)((1.0/255.0))));           \
    (o)->blue  =                                                         \
        (((RwReal)(((i)->blue))) * (  (RwReal)((1.0/255.0))));           \
    (o)->alpha =                                                         \
        (((RwReal)(((i)->alpha))) * ( (RwReal)((1.0/255.0))));           \
}                                                                        \
MACRO_STOP

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */


#if (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))

#define RwRGBARealAdd(o,a,b) \
        RwRGBARealAddMacro(o,a,b)

#define RwRGBARealSub(o,a,b) \
        RwRGBARealSubMacro(o,a,b)

#define RwRGBARealScale(o,a,scale) \
        RwRGBARealScaleMacro(o,a,scale)

#define RwRGBAFromRwRGBAReal(o, i) \
        RwRGBAFromRwRGBARealMacro(o, i)

#define RwRGBARealFromRwRGBA(o, i) \
        RwRGBARealFromRwRGBAMacro(o, i)

#else /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */

/* Function versions for debug */
extern void RwRGBARealAdd(RwRGBAReal *result,
                          const RwRGBAReal *source1,
                          const RwRGBAReal *source2);

extern void RwRGBARealSub(RwRGBAReal *result,
                          const RwRGBAReal *source1,
                          const RwRGBAReal *source2);

extern void RwRGBARealScale(RwRGBAReal *result,
                            const RwRGBAReal *source,
                            RwReal scalar);

extern void RwRGBAFromRwRGBAReal(RwRGBA *result,
                                 const RwRGBAReal *source);

extern void RwRGBARealFromRwRGBA(RwRGBAReal *result,
                                 RwRGBA *source);

#endif /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/drvmodel.h ---*/
#ifndef SKY2_DRVMODEL_H
#define SKY2_DRVMODEL_H

/**
 * \defgroup driversky2 PS2
 * \ingroup rwcore
 *
 * PS2 drivers
 */

/**
 * \defgroup sky2unsupported Unsupported PS2 Functions
 * \ingroup driversky2
 *
 * Unsupported functions
 */

#if (!defined(RXPIPELINE))
#define RXPIPELINE
#endif /* (!defined(RXPIPELINE)) */
#ifndef _RW_EETYPES_H
#define _RW_EETYPES_H
#include <eetypes.h>
#endif /* _RW_EETYPES_H */

/****************************************************************************
 Defines
 */

/* Global size */
#define RWGLOBALSIZE (16*1024)

/* Cache Control */
 /* Normal adaptive LRU/MRU algorithm operation */
#define RWSKYCACHENORMAL    0  
/* Manual override, textures used while set are 
 * first candidates of purging (MRU) */
#define RWSKYCACHESTATIC    1   

/* Number of frames to average metrics over */
#define rwSKYMETRICSSAMPLES 8
/* log2 of number of frames per sample */
#define rwSKYMETRICSFRAMESPERSAMPLE 1

/* Metrowerks don't yet support this so guard */
#if (!defined(__MWERKS__))

#define RwFastRealToUInt32(valIn)               \
({                                              \
    float tmpFloat;                             \
    float floatIn = valIn;                      \
    RwUInt32 _result;                           \
                                                \
    __asm__  ("cvt.w.s %0, %2 \n                \
                       mfc1 %1, %0 \n           \
                  " : "=f" (tmpFloat),          \
                      "=r&" (_result)           \
                    : "f" (floatIn));           \
    _result;                                    \
})

#endif /* (!defined(__MWERKS__)) */

/* For now. Assumes inline does the right thing */
#if (defined(__MWERKS__)) && (!defined(RWDEBUG))

/* elided */

#endif /* (defined(__MWERKS__)) && (!defined(RWDEBUG)) */

#if (!defined(RwFastRealToUInt32))

#if (defined(__MWERKS__))
#if ( __MWERKS__ >= 0x2401)
/*
 * The following pragma is implemented in the MW 2.4 Compiler only:
 * - #pragma fast_fptosi on|off|reset
 * enabling this pragma will generate cvt.w.s instruction to
 * replace runtime function _fptosi.
 */
#pragma fast_fptosi on
#endif /* ( __MWERKS__ >= 0x2401)  */
#endif /* (defined(__MWERKS__)) */

#define RwFastRealToUInt32(valIn) ((RwUInt32)((RwReal)(valIn)))
#endif /* (!defined(RwFastRealToUInt32)) */

/* Set true depth information (for fogging, eg) */
/* I'm making this much like the Windows one, as we have to make RW4 apps */
/* less dependent of loads of fields set all over the place */
#define RwIm2DVertexSetCameraX(vert, camx)      /* Nothing */
#define RwIm2DVertexSetCameraY(vert, camy)      /* Nothing */
#define RwIm2DVertexSetCameraZ(vert, camz)      ((vert)->u.els.camVertex_z = (camz))
#define RwIm2DVertexSetRecipCameraZ(vert, recipz)     ((vert)->u.els.recipZ = (recipz))

#define RwIm2DVertexGetCameraX(vert)            (Bang!)
#define RwIm2DVertexGetCameraY(vert)            (Bang!)
#define RwIm2DVertexGetCameraZ(vert)            ((vert)->u.els.camVertex_z)
#define RwIm2DVertexGetRecipCameraZ(vert)             ((vert)->u.els.recipZ)

/* Set screen space coordinates in a device vertex */
#define RwIm2DVertexSetScreenX(vert, scrnx)     ((vert)->u.els.scrVertex.x = (scrnx))
#define RwIm2DVertexSetScreenY(vert, scrny)     ((vert)->u.els.scrVertex.y = (scrny))
#define RwIm2DVertexSetScreenZ(vert, scrnz)     ((vert)->u.els.scrVertex.z = (scrnz))
#define RwIm2DVertexGetScreenX(vert)            ((vert)->u.els.scrVertex.x)
#define RwIm2DVertexGetScreenY(vert)            ((vert)->u.els.scrVertex.y)
#define RwIm2DVertexGetScreenZ(vert)            ((vert)->u.els.scrVertex.z)

/* Set texture coordinates in a device vertex */
#define RwIm2DVertexSetU(vert, texu, recipz)    ((vert)->u.els.u = (texu))
#define RwIm2DVertexSetV(vert, texv, recipz)    ((vert)->u.els.v = (texv))
#define RwIm2DVertexGetU(vert)                  ((vert)->u.els.u)
#define RwIm2DVertexGetV(vert)                  ((vert)->u.els.v)

/* Modify the luminance stuff */
#define RwIm2DVertexSetRealRGBA(vert, r, g, b, a)       \
MACRO_START                                             \
{                                                       \
    ((vert)->u.els.color.red = (r));                    \
    ((vert)->u.els.color.green = (g));                  \
    ((vert)->u.els.color.blue = (b));                   \
    ((vert)->u.els.color.alpha = (a));                  \
}                                                       \
MACRO_STOP

#define RwIm2DVertexSetIntRGBA(vert, r, g, b, a)        \
MACRO_START                                             \
{                                                       \
    ((vert)->u.els.color.red = (RwReal)(r));            \
    ((vert)->u.els.color.green = (RwReal)(g));          \
    ((vert)->u.els.color.blue = (RwReal)(b));           \
    ((vert)->u.els.color.alpha = (RwReal)(a));          \
}                                                       \
MACRO_STOP

#define RwIm2DVertexGetRed(vert)       \
    ((RwUInt32)((vert)->u.els.color.red))

#define RwIm2DVertexGetGreen(vert)     \
    ((RwUInt32)((vert)->u.els.color.green))

#define RwIm2DVertexGetBlue(vert)      \
    ((RwUInt32)((vert)->u.els.color.blue))

#define RwIm2DVertexGetAlpha(vert)     \
    ((RwUInt32)((vert)->u.els.color.alpha))

#define RwIm2DVertexCopyRGBA(dst, src) \
    ((dst)->u.els.color = (src)->u.els.color)

/* Clipper stuff */
/* We don't use the clipper here, so it does something really noddy */
/* Yeah, thanks for that. :-( -- Simon */

#define RwIm2DVertexClipRGBA(out, interp, near, far)                      \
MACRO_START                                                               \
{                                                                         \
    RwInt32 fixinterp =                                                   \
        (RwInt32) /* floor */ (((interp) * 65536.0f) + 0.5f); /* 16:0 */  \
                                                                          \
    ((out)->u.els.color.red   =                                           \
     (near)->u.els.color.red   +                                          \
     ((((RwInt32) ((far)->u.els.color.red  -(near)->u.els.color.red  )) * \
       fixinterp + 32768) >> 16));                                        \
                                                                          \
    ((out)->u.els.color.green =                                           \
     (near)->u.els.color.green +                                          \
     ((((RwInt32) ((far)->u.els.color.green-(near)->u.els.color.green)) * \
       fixinterp + 32768) >> 16));                                        \
                                                                          \
    ((out)->u.els.color.blue  =                                           \
     (near)->u.els.color.blue  +                                          \
     ((((RwInt32) ((far)->u.els.color.blue -(near)->u.els.color.blue )) * \
       fixinterp + 32768) >> 16));                                        \
                                                                          \
    ((out)->u.els.color.alpha =                                           \
     (near)->u.els.color.alpha +                                          \
     ((((RwInt32) ((far)->u.els.color.alpha-(near)->u.els.color.alpha)) * \
       fixinterp + 32768) >> 16));                                        \
}                                                                         \
MACRO_STOP

/* LEGACY-SUPPORT macros */
#define RWIM2DVERTEXSetCameraX(_v, _cx)  RwIm2DVertexSetCameraX(_v, _cx)
#define RWIM2DVERTEXSetCameraY(_v, _cy)  RwIm2DVertexSetCameraY(_v, _cy)
#define RWIM2DVERTEXSetCameraZ(_v, _cz)  RwIm2DVertexSetCameraZ(_v, _cz)
#define RWIM2DVERTEXSetRecipCameraZ(_v, _rz) \
                                         RwIm2DVertexSetRecipCameraZ(_v, _rz)
#define RWIM2DVERTEXGetCameraX(_v)       RwIm2DVertexGetCameraX(_v)
#define RWIM2DVERTEXGetCameraY(_v)       RwIm2DVertexGetCameraY(_v)
#define RWIM2DVERTEXGetCameraZ(_v)       RwIm2DVertexGetCameraZ(_v)
#define RWIM2DVERTEXGetRecipCameraZ(_v)  RwIm2DVertexGetRecipCameraZ(_v)
#define RWIM2DVERTEXSetScreenX(_v, _sx)  RwIm2DVertexSetScreenX(_v, _sx)
#define RWIM2DVERTEXSetScreenY(_v, _sy)  RwIm2DVertexSetScreenY(_v, _sy)
#define RWIM2DVERTEXSetScreenZ(_v, _sz)  RwIm2DVertexSetScreenZ(_v, _sz)
#define RWIM2DVERTEXGetScreenX(_v)       RwIm2DVertexGetScreenX(_v)
#define RWIM2DVERTEXGetScreenY(_v)       RwIm2DVertexGetScreenY(_v)
#define RWIM2DVERTEXGetScreenZ(_v)       RwIm2DVertexGetScreenZ(_v)
#define RWIM2DVERTEXSetU(_v, u, _rz)     RwIm2DVertexSetU(_v, u, _rz)
#define RWIM2DVERTEXSetV(_v, v, _rz)     RwIm2DVertexSetV(_v, v, _rz)
#define RWIM2DVERTEXGetU(_v)             RwIm2DVertexGetU(_v)
#define RWIM2DVERTEXGetV(_v)             RwIm2DVertexGetV(_v)
#define RWIM2DVERTEXSetRealRGBA(_v, _r, _g, _b, _a) \
                                RwIm2DVertexSetRealRGBA(_v, _r, _g, _b, _a)
#define RWIM2DVERTEXSetIntRGBA(_v, _r, _g, _b, _a)  \
                                 RwIm2DVertexSetIntRGBA(_v, _r, _g, _b, _a)
#define RWIM2DVERTEXGetRed(_v)           RwIm2DVertexGetRed(_v)
#define RWIM2DVERTEXGetGreen(_v)         RwIm2DVertexGetGreen(_v)
#define RWIM2DVERTEXGetBlue(_v)          RwIm2DVertexGetBlue(_v)
#define RWIM2DVERTEXGetAlpha(_v)         RwIm2DVertexGetAlpha(_v)
#define RWIM2DVERTEXCopyRGBA(dst, src)   RwIm2DVertexCopyRGBA(dst, src)
#define RWIM2DVERTEXClipRGBA(o, i, n, f) RwIm2DVertexClipRGBA(o, i, n, f)

#undef rwInvSqrtOldMacro
#define rwInvSqrtOldMacro(_recip, _input)                                 \
MACRO_START                                                               \
{                                                                         \
    if ((_input) !=0)                                                     \
    {                                                                     \
        static const float _one = 1.0f;                                   \
        asm ("rsqrt.s %0, %1, %2" :                                       \
                      "=f" (_recip) : "f" (_one) , "f" (_input) : "cc");  \
    }                                                                     \
    else                                                                  \
    {                                                                     \
        (_recip) = (_input);                                              \
    }                                                                     \
}                                                                         \
MACRO_STOP

#undef rwSqrtMacro
#undef rwInvSqrtMacro
#undef rwSqrtInvSqrtMacro

#if (defined(__MWERKS__))

/*
 * mwccps2 doesn't like having a '.' in the name of an assembler
 * result variable, so go via "_result" to be on the safe side ..
 */

#define rwSqrtMacro(_root, _input)                                        \
MACRO_START                                                               \
{                                                                         \
    RwReal  _result = (RwReal)0;                                          \
    RwReal  _tmp = _input;                                                \
    asm ("sqrt.s %0, %1" : "=f" (_result) : "f" (_tmp) : "cc");           \
    _root = _result;                                                      \
}                                                                         \
MACRO_STOP

#define rwInvSqrtMacro(_recip, _input)                                    \
MACRO_START                                                               \
{                                                                         \
    RwReal  _result = (RwReal)0;                                          \
    asm ("sqrt.s %0, %1" : "=f" (_result) : "f" (_input) : "cc");         \
    (_recip) = (_result > 0) ? ( ((RwReal)1)/(_result) ) : (_result);     \
}                                                                         \
MACRO_STOP

#define rwSqrtInvSqrtMacro(_root, _recip, _input)                         \
MACRO_START                                                               \
{                                                                         \
    RwReal  _result = (RwReal)0;                                          \
    asm ("sqrt.s %0, %1" : "=f" (_result) : "f" (_input) : "cc");         \
    _root = _result;                                                      \
    (_recip) = (_root > 0) ? ( ((RwReal)1)/(_root) ) : (_root);           \
}                                                                         \
MACRO_STOP

#endif /* (defined(__MWERKS__)) */

#if (!defined(rwSqrtMacro))
#define rwSqrtMacro(_root, _input)                                        \
MACRO_START                                                               \
{                                                                         \
    asm ("sqrt.s %0, %1" : "=f" (_root) : "f" (_input) : "cc");           \
}                                                                         \
MACRO_STOP
#endif /* (!defined(rwSqrtMacro)) */

#if (!defined(rwInvSqrtMacro))
#define rwInvSqrtMacro(_recip, _input)                                    \
MACRO_START                                                               \
{                                                                         \
    asm ("sqrt.s %0, %1" : "=f" (_recip) : "f" (_input) : "cc");          \
    (_recip) = (_recip > 0) ? ( ((RwReal)1)/(_recip) ) : (_recip);        \
}                                                                         \
MACRO_STOP
#endif /* (!defined(rwInvSqrtMacro)) */

#if (!defined(rwSqrtInvSqrtMacro))
#define rwSqrtInvSqrtMacro(_root, _recip, _input)                         \
MACRO_START                                                               \
{                                                                         \
    asm ("sqrt.s %0, %1" : "=f" (_root) : "f" (_input) : "cc");           \
    _root = _root;                                                        \
    (_recip) = (_root > 0) ? ( ((RwReal)1)/(_root) ) : (_root);           \
}                                                                         \
MACRO_STOP
#endif /* (!defined(rwSqrtInvSqrtMacro)) */

#if (!defined(USEINTVAR))
#if (defined(__MWERKS__))
/* Stop CW complaining about variables being unused if they are used, 
 * but only in inline asm */
#define USEINTVAR(_var) ((0)?((_var) = 0):(0))
#else /* (defined(__MWERKS__)) */
#define USEINTVAR(_var) /* No op */
#endif /* (defined(__MWERKS__)) */
#endif /* (!defined(USEINTVAR)) */

#define RwMatrixMultiplyVUMacro(_matrix, _matrixIn1, _matrixIn2)    \
MACRO_START                                                         \
{                                                                   \
    int __tmp1, __tmp2;                                             \
    USEINTVAR(__tmp1);                                              \
    USEINTVAR(__tmp2);                                              \
                                                                    \
    asm __volatile__ (".set noreorder                               \n\
        lqc2        vf1,  0x00(%2)                                  \n\
        lqc2        vf2,  0x10(%2)                                  \n\
        lqc2        vf3,  0x20(%2)                                  \n\
        lqc2        vf4,  0x30(%2)                                  \n\
        lwu         %0,   0x0C(%2)                                  \n\
        lqc2        vf5,  0x00(%3)                                  \n\
        lqc2        vf6,  0x10(%3)                                  \n\
        lqc2        vf7,  0x20(%3)                                  \n\
        lqc2        vf8,  0x30(%3)                                  \n\
        lwu         %1,   0x0C(%3)                                  \n\
        vmulax.xyz  ACC,  vf5, vf1                                  \n\
        vmadday.xyz ACC,  vf6, vf1                                  \n\
        vmaddz.xyz  vf9,  vf7, vf1                                  \n\
        vmulax.xyz  ACC,  vf5, vf2                                  \n\
        vmadday.xyz ACC,  vf6, vf2                                  \n\
        vmaddz.xyz  vf10, vf7, vf2                                  \n\
        vmulax.xyz  ACC,  vf5, vf3                                  \n\
        vmadday.xyz ACC,  vf6, vf3                                  \n\
        vmaddz.xyz  vf11, vf7, vf3                                  \n\
        vmulax.xyz  ACC,  vf5, vf4                                  \n\
        vmadday.xyz ACC,  vf6, vf4                                  \n\
        vmaddaz.xyz ACC,  vf7, vf4                                  \n\
        vmaddw.xyz  vf12, vf8, vf0                                  \n\
        and         %1, %1, %0                                      \n\
        sqc2        vf9,  0x00(%4)                              \n\
        sqc2        vf10, 0x10(%4)                              \n\
        sqc2        vf11, 0x20(%4)                              \n\
        sqc2        vf12, 0x30(%4)                              \n\
        sw          %1, 0x0C(%4)                                    \n\
        .set reorder "                                              \
         : "=r&" (__tmp1), "=r&" (__tmp2) : "r" (_matrixIn1),       \
           "r" (_matrixIn2), "r" (_matrix) : "cc",  "memory");      \
}                                                                   \
MACRO_STOP

#if (!defined(_RW_MATMUL_CPU) && !defined(RwMatrixMultiplyMacro))
#define RwMatrixMultiplyMacro(_m, _m1, _m2) \
        RwMatrixMultiplyVUMacro(_m, _m1, _m2)
#endif /* (!defined(_RW_MATMUL_CPU) && !defined(RwMatrixMultiplyMacro)) */

#if ( (defined(RWMEMDEBUG)) && defined(RWDEBUG) )

/*
 * PS2 memdebug build requires linking with librtdbmalloc.a
 */

#include <rtdbmalloc.h>

#undef RwMalloc
#define RwMalloc(p_Size) \
    RtDBMalloc(__FILE__, __LINE__, (p_Size))

#undef RwCalloc
#define RwCalloc(p_Number, p_Size)    \
    RtDBCalloc(__FILE__, __LINE__, (p_Number), (p_Size))

#undef RwRealloc
#define RwRealloc(p_Name, p_Size) \
    RtDBRealloc(__FILE__, __LINE__, (p_Name), (p_Size))

#undef RwFree
#define RwFree(p_Name) \
    RtDBFree(__FILE__, __LINE__, (p_Name))

#undef RWPENTER
#define RWPENTER(_func)    RtDBStackEnter(_func,__FILE__,__LINE__)

#undef RWPEXIT
#define RWPEXIT(_func)     RtDBStackLeave(_func,__FILE__,__LINE__)

#undef RWASSERTE
#define RWASSERTE(_condition)                                              \
MACRO_START                                                                \
{                                                                          \
    if (!(_condition))                                                     \
    {                                                                      \
        printf("%s(%d): assertion failure [%s]\n",                         \
               __FILE__, __LINE__, #_condition);                           \
        RtDBStackDump("RW stack on failure of [" ## #_condition ## "]:\n", \
                      RtDBStackCurrent());                                 \
    }                                                                      \
}                                                                          \
MACRO_STOP

#endif /* ( (defined(RWMEMDEBUG)) && defined(RWDEBUG) ) */

/****************************************************************************
 Global Types
 */

/**
 * $ingroup driversky2
 * $typedef RwSky2DVertexFields
 */
typedef struct RwSky2DVertexFields RwSky2DVertexFields;
/**
 * \ingroup driversky2
 * \struct RwSky2DVertexFields
 * Structure for 2D vertex fields
 */
struct RwSky2DVertexFields
{
    RwV3d          scrVertex;              /**< Object space vertex */
    RwReal         camVertex_z;            /**< Camera space z (for fog table) */
    RwReal         u;                      /**< Texture coordinate */
    RwReal         v;                      /**< Texture coordinate */
    RwReal         recipZ;                 /**< Recipz */
    RwReal         pad1;                   /**< Padding (fog table) */
    RwRGBAReal     color;                  /**< Color */
    RwV3d          objNormal;              /**< We allocate this, even though
                                            * we don't use it - we may want
                                            * to later.
                                            */
    RwReal         pad2;                   /**< Alignment padding */
};

/**
 * $ingroup driversky2
 * $typedef RwSky2DVertexAlignmentOverlay
 */
typedef union RwSky2DVertexAlignmentOverlay RwSky2DVertexAlignmentOverlay;
/**
 * \ingroup driversky2
 * \union RwSky2DVertexAlignmentOverlay
 * Union allowing access to \ref RwSky2DVertexFields as a 4 quad words
 */
union RwSky2DVertexAlignmentOverlay
{
    RwSky2DVertexFields els;                            /**< Internal use */
    u_long128 qWords[4];                                /**< Internal use */
};

/**
 * $ingroup driversky2
 * $typedef RwSky2DVertex
 */
typedef struct RwSky2DVertex RwSky2DVertex;
/**
 * \ingroup driversky2
 * \struct RwSky2DVertex
 * Structure for 2D vertex
 */
struct RwSky2DVertex
{
    RwSky2DVertexAlignmentOverlay u;                    /**< Internal use */
};

/* Define types used */
/**
 * \ingroup driversky2
 * \typedef RwIm2DVertex
 * Typedef for a RenderWare Graphics Immediate Mode 2D Vertex
 */
typedef RwSky2DVertex   RwIm2DVertex;
/* LEGACY-SUPPORT macro */

/**
 * \ingroup driversky2
 * \def RWIM2DVERTEX
 * RWIM2DVERTEX is a legacy macro for RwIm2DVertex
 */

#define RWIM2DVERTEX    RwIm2DVertex

/**
 * \ingroup driversky2
 * \typedef RxVertexIndex
 * Typedef for a RenderWare Graphics PowerPipe Immediate Mode Vertex
 */
typedef RwUInt16        RxVertexIndex;

/**
 * \ingroup driversky2
 * \typedef RwImVertexIndex
 * Typedef for a RenderWare Graphics Immediate Mode Vertex
 */
typedef RxVertexIndex   RwImVertexIndex;

/* LEGACY-SUPPORT macro */
/**
 * \ingroup driversky2
 * \def RWIMVERTEXINDEX
 * RWIMVERTEXINDEX is a legacy macro for RwImVertexIndex
 */
#define RWIMVERTEXINDEX RwImVertexIndex


/**
 * $ingroup driversky2
 * $typedef RwSkyMetrics
 */
typedef struct RwSkyMetrics RwSkyMetrics;
/**
 * \ingroup driversky2
 * \struct RwSkyMetrics
 * Structure containing metrics counters
 */
struct RwSkyMetrics
{
    RwUInt32 profTotal;                                 /**< Internal use */
    RwUInt32 vu1Running;                                /**< Internal use */
    RwUInt32 dma1Running;                               /**< Internal use */
    RwUInt32 dma2Running;                               /**< Internal use */
    /* Internal1 is the time over which dma1 is stalled on vu and no GIF
     * transfer is taking place. */
    RwUInt32 internal1;                                 /**< Internal use */
    RwUInt32 vSyncsSinceLastFlip;                       /**< Internal use */
    RwUInt64 flipPktTime;                               /**< Internal use */
    RwUInt32 totalVSyncsOverPeriod;                     /**< Internal use */

    RwUInt32 curFrame;                                  /**< Internal use */
    RwUInt32 frameProfTotal[rwSKYMETRICSSAMPLES];       /**< Internal use */
    RwUInt32 frameVu1Running[rwSKYMETRICSSAMPLES];      /**< Internal use */
    RwUInt32 frameDma1Running[rwSKYMETRICSSAMPLES];     /**< Internal use */
    RwUInt32 frameDma2Running[rwSKYMETRICSSAMPLES];     /**< Internal use */
    RwUInt32 frameinternal1[rwSKYMETRICSSAMPLES];       /**< Internal use */
    RwUInt32 frameVSyncsOverPeriod[rwSKYMETRICSSAMPLES]; /**< Internal use */
    RwUInt32 lastFrameVSyncCount;                       /**< Internal use */
    RwUInt64 flipPktToFlipTime;                         /**< Internal use */
};

#endif /* SKY2_DRVMODEL_H */


/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/badma.h ---*/
#ifndef _RW_EETYPES_H
#define _RW_EETYPES_H
#include <eetypes.h>
#endif /* _RW_EETYPES_H */

#ifndef _RW_EEKERNEL_H
#define _RW_EEKERNEL_H
#include <eekernel.h>
#endif /* _RW_EEKERNEL_H */

#ifndef _RW_LIBDMA_H
#define _RW_LIBDMA_H
#include <libdma.h>
#endif /* _RW_LIBDMA_H */

#ifndef RWDEBUG
#define LOCAL_REG_SUPPORT
#endif /* RWDEBUG */

/* flags in top bits */
#define SWE_PKT_LOCAL       0x80000000
#define SWE_PKT_PROCESSED   0x40000000
#define SWE_PKT_NONCONTIG   0x20000000
#define SWE_PKT_SWAP        0x10000000
#define SWE_PKT_CIRCALLOC       0x08000000

#define SWE_PKT_TYPE_MASK   0xff
/* Real packets */
#define SWE_PKT_VU0     0x00
#define SWE_PKT_VU1     0x01
#define SWE_PKT_GIF     0x02

#define SWE_PKT_ASYNC       0x40
#define SWE_PKT_AGIF        (SWE_PKT_ASYNC | SWE_PKT_GIF)

/* Fake packets */
#define SWE_PKT_FLIP0       0x80
#define SWE_PKT_FLIP1       0x81
#define SWE_PKT_RASUREF         0x82
#define SWE_PKT_NULL            0x83

#define SWE_PKT_IMM_MASK        0xffff00
#define SWE_PKT_IMM_SHIFT       8
#define SWE_PKT_IMM_MAX         (SWE_PKT_IMM_MASK>>SWE_PKT_IMM_SHIFT)

/* Sort of dma we want */
#define SWE_PKT_DMA_MODE_MASK       0x300
#define SWE_PKT_DMA_MODE_NORM       0x000
#define SWE_PKT_DMA_MODE_CHAIN      0x100
#define SWE_PKT_DMA_MODE_INTERL     0x200
#define SWE_PKT_DMA_MODE_CHAIN_TTE  0x500
/* Amount of shift to match mod field of Dn_CHCR reg */
#define SWE_DMA_MODE_SHIFT            6

/* Jump to new memory block */
#define SWE_PKT_GOTO        0xff

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */
extern RwBool sweOpenLocalPkt(int type, int size);
extern void sweCloseLocalPkt(void);
#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


#ifndef SWE_LPS_CONT
#define SWE_LPS_CONT 1
#endif /* SWE_LPS_CONT */

#ifndef SWE_LPS_PRIM
#define SWE_LPS_PRIM 2
#endif /* SWE_LPS_PRIM */

#ifndef SWE_LPS_NOFIXUP
#define SWE_LPS_NOFIXUP 0x80000000
#endif /* SWE_LPS_NOFIXUP */

/* Use this define to turn off excess EOP's in GIF tags */
#define LESSEOPSx

/* Use this define to use direct access */
#define USEDIRECTx


#if (defined(__MWERKS__))
/* MW version of /usr/local/sce/ee/include/eekernel.h:DI() */
/* MW specific overload removed. */
#endif /* (defined(__MWERKS__)) */

/* Critical section wrappers (for making access to variables modified
 * in interrupt handlers)
 */
#define START_CRITICAL_SECTION \
    DI()
#define END_CRITICAL_SECTION \
    EI()

typedef struct swe_pkt swe_pkt;
struct swe_pkt
{
    unsigned int type;   /**< Internal use */
    void *addr;          /**< Internal use */
};

typedef struct _rwSkyTwoCircuit _rwSkyTwoCircuit;
struct _rwSkyTwoCircuit
{
    RWALIGN(u_long128 dmaDisp1[4], 64); /**< Internal use */
    RWALIGN(u_long128 dmaDisp2[4], 64); /**< Internal use */
    tGS_DISPFB1     dispfb10;           /**< Internal use */
    tGS_DISPLAY1    display10;          /**< Internal use */ 
    tGS_DISPFB1     dispfb11;           /**< Internal use */
    tGS_DISPLAY1    display11;          /**< Internal use */
};

extern _rwSkyTwoCircuit tcaaDisp;

/*
 * MWERKS needs these to be declared
 * before they can be used further down in a #define
 */
#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

extern long sweFrameRenderCount;
extern int sweUseHalfOffset;
extern volatile long sweCurrentHalfOffset;
extern volatile int sweNumFlipsInQueue;
extern volatile int sweFlipPending;
extern volatile int sweAutoFlip;

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

#if (defined(__MWERKS__))

#if (defined(RWVERBOSE))
#pragma message (__FILE__ "/" _SKY_EXPAND(__LINE__) ": __MWERKS__ == " _SKY_EXPAND(__MWERKS__))
#endif /* (defined(RWVERBOSE)) */

#define SWE_HALF_OFFSET_MACRO(_result)                  \
MACRO_START                                             \
{                                                       \
    if (sweUseHalfOffset)                               \
    {                                                   \
        DI();                                           \
        (_result) =                                     \
            (sweCurrentHalfOffset ^                     \
             (sweNumFlipsInQueue&1)^sweFlipPending);    \
        EI();                                           \
    }                                                   \
    else                                                \
    {                                                   \
        (_result) = (0l);                               \
    }                                                   \
}                                                       \
MACRO_STOP

static inline long
SWE_HALF_OFFSET(void)
{
    long result;
    SWE_HALF_OFFSET_MACRO(result);

    return result;
}

#else /* (defined(__MWERKS__)) */

/* This is complicated */
#define SWE_HALF_OFFSET()                        \
    (sweUseHalfOffset?                           \
    ({ long __res;                           \
      DI();                              \
      __res =                                                        \
              ( sweCurrentHalfOffset ^                                   \
               ( sweNumFlipsInQueue&1 ) ^                                \
               sweFlipPending );                                         \
      EI();                              \
      __res; })                          \
    :0l)

#define SWE_HALF_OFFSET_MACRO(_result)          \
MACRO_START                                     \
{                                               \
    (_result) = SWE_HALF_OFFSET();              \
}                                               \
MACRO_STOP

#endif /* (defined(__MWERKS__)) */

#define _sweAddVU0(A) _sweAddPkt(A, SWE_PKT_VU0)
#define _sweAddVU1(A) _sweAddPkt(A, SWE_PKT_VU1)
#define _sweAddGIF(A) _sweAddPkt(A, SWE_PKT_GIF)

/* we use this sometimes */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

extern RwBool _sweHook(void);
extern RwBool _sweOpen(void);
extern void _sweUnhook(void);
extern void _sweClose(void);
extern void _sweFlush(void);
extern void _sweReqFlip(void *addr, int id, unsigned int flags);
extern void _sweWaitFlip(void);
extern void _sweGarbageCollectChain(void);
extern RwBool _sweAddPkt(void* addr, int ch);
extern RwBool _sweAppendToChain(void *addr, void *link);
extern void _sweProcrastinatedAddURef(unsigned int *ptr);

/* Stealth functions */
extern void sweFlushPURef(void);

extern RwBool _swePreAlloc(int memory, int chain, RwBool limit);

extern void sweDmaSend(sceDmaChan *d, void *tag, unsigned int extra);

extern RwBool sweFinaliseOpenLocalPkt(int type, int size);

/* We define the max size and check for inconsistency */
#ifndef SWE_LPS_MAX_PACKET_SIZE
#define SWE_LPS_MAX_PACKET_SIZE 1022
#else /* !SWE_LPS_MAX_PACKET_SIZE */
#if (SWE_LPS_MAX_PACKET_SIZE != 1022)
#error "Definitions of SWE_LPS_MAX_PACKET_SIZE in badma.{c,h} conflict"
#endif
#endif /* !SWE_LPS_MAX_PACKET_SIZE */

/* We define a max qword count for image ops */
#define SWE_LPS_MAX_IMG_QWC \
        (SWE_LPS_MAX_PACKET_SIZE-17>32750?32750:SWE_LPS_MAX_PACKET_SIZE-17)

#ifdef LESSEOPS
/* GIF tag to qword data count */
#define SWEGIFTOSIZE(A) \
({                  \
    u_long128 input = (A);      \
    unsigned int tmp;           \
    unsigned int tmp2;          \
    unsigned int result;        \
    __asm__ ("  andi    %0, %3, 0x7fff  \n\
        dsrl32  %2, %3, 0x1c    \n\
        dsrl32  %1, %3, 0x1a    \n\
        andi    %2, %2, 0xf \n\
        andi    %1, %1, 0x3 \n\
        addiu   %2, %2, 1   \n\
        multu   %0, %2      \n\
.set noreorder              \n\
.set nomacro                \n\
        beq %1, $0, 0f  \n\
        addiu   %1, %1, -1  \n\
        beq %1, $0, 1f  \n\
        nop         \n\
        beq $0, $0, 2f  \n\
        nop         \n\
.set macro              \n\
.set reorder                \n\
0:                  \n\
.set noreorder              \n\
.set nomacro                \n\
        beq $0, $0, 2f  \n\
1:      mflo    %0      \n\
.set macro              \n\
.set reorder                \n\
        addui   %0, %0, 1   \n\
        dsrl    %0, %0, 1   \n\
2:                  \n\
             " : "=r&" (result),    \
             "=r&" (tmp)        \
             "=r&" (tmp2)       \
               : "r" (input));      \
    result;             \
})
#endif /* LESSEOPS */

/* These shouldn't be functions, they need to be much lighter weight...  */

extern void _sweAddCont(u_long128 arg);
extern void _sweAddPrim(u_long128 arg);

/* ... so we wrap them as follows: */
/* These can only be used if a packet of the correct type is known to be open */
extern u_long128 *sweLocalPacket;
extern u_long128 *sweLocalPacketHigh;

#ifdef LESSEOPS
extern unsigned int sweLocalPacketGifQWC;
#endif /* LESSEOPS */

#ifdef LESSEOPS
#define SWEADDCONT(A)               \
sweLocalPacketGifQWC--;             \
if (sweLocalPacket < sweLocalPacketHigh)    \
{                       \
    *sweLocalPacket++ = (A);            \
}                       \
else                        \
{                       \
    _sweAddCont(A);             \
}
#else /* LESSEOPS */
#define SWEADDCONT(A)               \
if (sweLocalPacket < sweLocalPacketHigh)    \
{                       \
    *sweLocalPacket++ = (A);            \
}                       \
else                        \
{                       \
    _sweAddCont(A);             \
}
#endif /* LESSEOPS */

#ifdef LESSEOPS
#define SWEADDCONTGIF(A)            \
if (sweLocalPacket < sweLocalPacketHigh)    \
{                       \
    *sweLocalPacket++ = (A);            \
}                       \
else                        \
{                       \
    _sweAddCont(A);             \
}                       \
sweLocalPacketGifQWC = SWEGIFTOSIZE(A)
#else /* LESSEOPS */
#define SWEADDCONTGIF(A)            \
if (sweLocalPacket < sweLocalPacketHigh)    \
{                       \
    *sweLocalPacket++ = (A);            \
}                       \
else                        \
{                       \
    _sweAddCont(A);             \
}
#endif /* LESSEOPS */

#ifdef LESSEOPS
#define SWEADDPRIM(A)               \
sweLocalPacketGifQWC--;             \
if (sweLocalPacket < sweLocalPacketHigh)    \
{                       \
    *sweLocalPacket++ = (A);            \
}                       \
else                        \
{                       \
    _sweAddPrim(A);             \
}
#else /* LESSEOPS */
#define SWEADDPRIM(A)               \
if (sweLocalPacket < sweLocalPacketHigh)    \
{                       \
    *sweLocalPacket++ = (A);            \
}                       \
else                        \
{                       \
    _sweAddPrim(A);             \
}
#endif /* LESSEOPS */

#ifdef LESSEOPS
#define SWEADDPRIMGIF(A)            \
if (sweLocalPacket < sweLocalPacketHigh)    \
{                       \
    *sweLocalPacket++ = (A);            \
}                       \
else                        \
{                       \
    _sweAddPrim(A);             \
}                       \
sweLocalPacketGifQWC = SWEGIFTOSIZE(A)
#else /* LESSEOPS */
#define SWEADDPRIMGIF(A)            \
if (sweLocalPacket < sweLocalPacketHigh)    \
{                       \
    *sweLocalPacket++ = (A);            \
}                       \
else                        \
{                       \
    _sweAddPrim(A);             \
}
#endif /* LESSEOPS */

/* These can only be used if a packet of the correct type is known to be open
   and contains sufficient space */

#ifdef LESSEOPS
#define SWEADDCONTFAST(A)               \
    sweLocalPacketGifQWC--;             \
    *sweLocalPacket++ = (A)
#define SWEADDPRIMFAST(A)               \
    sweLocalPacketGifQWC--;             \
    *sweLocalPacket++ = (A)

#define SWEADDCONTGIFFAST(A, C)             \
    sweLocalPacketGifQWC = (C);             \
    *sweLocalPacket++ = (A)
#define SWEADDPRIMGIFFAST(A, C)             \
    sweLocalPacketGifQWC = (C);             \
    *sweLocalPacket++ = (A)
#else /* LESSEOPS */
/**
 * \ingroup sky2unsupported
 * \ref SWEADDCONTFAST
 * The macro \ref SWEADDCONTFAST adds a
 * quadword to the currently open local packet. It does no error checking.
 * For this library build, this is functionally equivalent to
 * \ref SWEADDPRIMFAST, \ref SWEADDCONTGIFFAST or \ref SWEADDPRIMGIFFAST
 *
 * \param  A   the quadword to be added.
 */
#define SWEADDCONTFAST(A)               \
    *sweLocalPacket++ = (A)
/**
 * \ingroup sky2unsupported
 * \ref SWEADDPRIMFAST 
 * The macro \ref SWEADDPRIMFAST adds a
 * quadword to the currently open local packet. It does no error checking.
 * For this library build, this is functionally equivalent to
 * \ref SWEADDCONTFAST, \ref SWEADDCONTGIFFAST or \ref SWEADDPRIMGIFFAST
 *
 * \param  A   the quadword to be added.
 */
#define SWEADDPRIMFAST(A)               \
    *sweLocalPacket++ = (A)

/**
 * \ingroup sky2unsupported
 * \ref SWEADDCONTGIFFAST 
 * The macro \ref SWEADDCONTGIFFAST
 * adds a quadword to the currently open local packet. It does no error
 * checking. For this library build, this is functionally equivalent to
 * \ref SWEADDCONTFAST, \ref SWEADDPRIMFAST or \ref SWEADDPRIMGIFFAST
 *
 * \param  A   the quadword to be added.
 * \param  C   The GIF tag NLOOP field (ignored)
 */
#define SWEADDCONTGIFFAST(A, C)             \
    *sweLocalPacket++ = (A)
/**
 * \ingroup sky2unsupported
 * \ref SWEADDPRIMGIFFAST
 * The macro \ref SWEADDPRIMGIFFAST
 * adds a quadword to the currently open local packet. It does no error
 * checking. For this library build, this is functionally equivalent to
 * \ref SWEADDCONTFAST, \ref SWEADDPRIMFAST or \ref SWEADDCONTGIFFAST
 *
 * \param  A   the quadword to be added.
 * \param  C   The GIF tag NLOOP field (ignored)
 */
#define SWEADDPRIMGIFFAST(A, C)             \
    *sweLocalPacket++ = (A)

#ifdef LOCAL_REG_SUPPORT
/* This is a solution to the non-optimal code generated due to sweLocalPacket
   being global. It relies on the fact that at -03, the const and if boils
   off, leaving the appropriate code only */

static const int sweInLocalBlock = 0;

extern u_long128 *__localLocalPacketPointer;

#define SWE_LOCAL_BLOCK_BEGIN()                            \
do                                                         \
{                                                          \
    const int sweInLocalBlock = 1;                         \
    u_long128 *__localLocalPacketPointer = sweLocalPacket

#define SWE_LOCAL_BLOCK_END()                              \
    sweLocalPacket = __localLocalPacketPointer;            \
} while (0)

#undef SWEADDCONTFAST
#undef SWEADDPRIMFAST
#undef SWEADDCONTGIFFAST
#undef SWEADDPRIMGIFFAST

#define SWEADDCONTFAST(A)                   \
do                                          \
{                                           \
    if (sweInLocalBlock)                    \
        *__localLocalPacketPointer++ = (A); \
    else                                    \
        *sweLocalPacket++ = (A);            \
}                                           \
while (0)

#define SWEADDPRIMFAST(A)               \
    SWEADDCONTFAST(A)

#define SWEADDCONTGIFFAST(A, C)             \
    SWEADDCONTFAST(A)

#define SWEADDPRIMGIFFAST(A, C)             \
    SWEADDCONTFAST(A)

#else /* LOCAL_REG_SUPPORT */

#define SWE_LOCAL_BLOCK_BEGIN()
#define SWE_LOCAL_BLOCK_END()

#endif /* LOCAL_REG_SUPPORT */

#endif /* LESSEOPS */

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* For external PL2 that wants to use dma allocator */
extern circularAllocator *circAllocator;
/* Debugging VIF Mark generation */
#define DEBUGWITHMARK

#ifdef DEBUGWITHMARK
extern unsigned int sweDebugMark;

#define DEBUGMARK() \
    ((7l<<24) | (unsigned long)(sweDebugMark++ & 0xffff))

#else /* DEBUGWITHMARK */

#define DEBUGMARK() (0l)

#endif /* DEBUGWITHMARK */
#if (!defined(RXPIPELINE))
#define RXPIPELINE
#endif /* (!defined(RXPIPELINE)) */

/*--- Automatically derived from: E:/nightly/rwsdk/src/bavector.h ---*/

/*
 * Typedef for pointer to Vector multiplication by Matrix function
 */

typedef RwV3d *(*rwVectorMultFn) (RwV3d * pointsOut, 
                                  const RwV3d * pointsIn,
                                  RwInt32 numPoints,
                                  const RwMatrix * matrix);


#if (!defined(rwSqrtMacro))
#define rwSqrtMacro(_root, _input)              \
MACRO_START                                     \
{                                               \
    (_root) = _rwSqrt((_input));                \
}                                               \
MACRO_STOP
#endif /* (!defined(rwSqrtMacro)) */

#if (!defined(rwInvSqrtMacro))
#define rwInvSqrtMacro(_recip, _input)          \
MACRO_START                                     \
{                                               \
    (_recip) = _rwInvSqrt((_input));            \
}                                               \
MACRO_STOP
#endif /* (!defined(rwInvSqrtMacro)) */

#if (!defined(rwSqrtInvSqrtMacro))
#define rwSqrtInvSqrtMacro(_root, _recip, _input)       \
MACRO_START                                             \
{                                                       \
    (_root) = _rwSqrt((_input));                        \
    (_recip) = _rwInvSqrt((_input));                    \
}                                                       \
MACRO_STOP
#endif /* (!defined(rwSqrtInvSqrtMacro)) */

/* Vector operations Macros */

#if (!defined(RwV2dAssignMacro))
#define RwV2dAssignMacro(_target, _source)                      \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwV2dAssignMacro)) */

#define RwV2dAddMacro(o, a, b)                                  \
MACRO_START                                                     \
{                                                               \
    (o)->x = (((a)->x) + ( (b)->x));                            \
    (o)->y = (((a)->y) + ( (b)->y));                            \
}                                                               \
MACRO_STOP

#define RwV2dSubMacro(o, a, b)                                  \
MACRO_START                                                     \
{                                                               \
    (o)->x = (((a)->x) - ( (b)->x));                            \
    (o)->y = (((a)->y) - ( (b)->y));                            \
}                                                               \
MACRO_STOP

#define RwV2dScaleMacro(o, i, s)                                \
MACRO_START                                                     \
{                                                               \
    (o)->x = (((i)->x) * ( (s)));                               \
    (o)->y = (((i)->y) * ( (s)));                               \
}                                                               \
MACRO_STOP

#define RwV2dDotProductMacro(a,b)                               \
    (( ((((a)->x) * ( (b)->x))) +                               \
      ( (((a)->y) * ( (b)->y)))))                               \

#define _rwV2dNormalizeMacro(_result, _out, _in)                \
MACRO_START                                                     \
{                                                               \
    RwReal              length2 =                               \
        RwV2dDotProductMacro((_in), (_in));                     \
                                                                \
    rwInvSqrtMacro(_result, length2);                           \
                                                                \
    RwV2dScaleMacro((_out), (_in), (_result));                  \
}                                                               \
MACRO_STOP

#define RwV2dNormalizeMacro(_result, _out, _in)                 \
MACRO_START                                                     \
{                                                               \
    RwReal              length2 =                               \
        RwV2dDotProductMacro((_in), (_in));                     \
    RwReal              recip;                                  \
                                                                \
    rwSqrtInvSqrtMacro(_result,recip,length2);                  \
                                                                \
    RwV2dScaleMacro((_out), (_in), recip);                      \
}                                                               \
MACRO_STOP

#define RwV2dLengthMacro(_result, _in)                          \
MACRO_START                                                     \
{                                                               \
    (_result) = RwV2dDotProductMacro(_in, _in);                 \
    rwSqrtMacro(_result, _result);                              \
}                                                               \
MACRO_STOP

#define RwV2dLineNormalMacro(_o, _a, _b)                        \
MACRO_START                                                     \
{                                                               \
    RwReal recip;                                               \
                                                                \
    (_o)->y = (((_b)->x) - ( (_a)->x));                         \
    (_o)->x = (((_a)->y) - ( (_b)->y));                         \
    _rwV2dNormalizeMacro(recip, _o,_o);                         \
}                                                               \
MACRO_STOP

#define RwV2dPerpMacro(o, a)                                    \
MACRO_START                                                     \
{                                                               \
    (o)->x = -(a)->y;                                           \
    (o)->y = (a)->x;                                            \
}                                                               \
MACRO_STOP

/* RwV3d */

#if (!defined(RwV3dAssignMacro))
#define RwV3dAssignMacro(_target, _source)                     \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwV3dAssignMacro)) */


#define RwV3dAddMacro(o, a, b)                                  \
MACRO_START                                                     \
{                                                               \
    (o)->x = (((a)->x) + ( (b)->x));                            \
    (o)->y = (((a)->y) + ( (b)->y));                            \
    (o)->z = (((a)->z) + ( (b)->z));                            \
}                                                               \
MACRO_STOP

#define RwV3dSubMacro(o, a, b)                                  \
MACRO_START                                                     \
{                                                               \
    (o)->x = (((a)->x) - ( (b)->x));                            \
    (o)->y = (((a)->y) - ( (b)->y));                            \
    (o)->z = (((a)->z) - ( (b)->z));                            \
}                                                               \
MACRO_STOP

#define RwV3dScaleMacro(o, a, s)                                \
MACRO_START                                                     \
{                                                               \
    (o)->x = (((a)->x) * ( (s)));                               \
    (o)->y = (((a)->y) * ( (s)));                               \
    (o)->z = (((a)->z) * ( (s)));                               \
}                                                               \
MACRO_STOP

#define RwV3dIncrementScaledMacro(o, a, s)                      \
MACRO_START                                                     \
{                                                               \
    (o)->x += (((a)->x) * ( (s)));                              \
    (o)->y += (((a)->y) * ( (s)));                              \
    (o)->z += (((a)->z) * ( (s)));                              \
}                                                               \
MACRO_STOP

#define RwV3dNegateMacro(o, a)                                  \
MACRO_START                                                     \
{                                                               \
    (o)->x = -(a)->x;                                           \
    (o)->y = -(a)->y;                                           \
    (o)->z = -(a)->z;                                           \
}                                                               \
MACRO_STOP

#define RwV3dDotProductMacro(a, b)                              \
    ((((( (((a)->x) * ((b)->x))) +                              \
        ( (((a)->y) * ((b)->y))))) +                            \
        ( (((a)->z) * ((b)->z)))))                              \

#define RwV3dCrossProductMacro(o, a, b)                         \
MACRO_START                                                     \
{                                                               \
    (o)->x =                                                    \
        (( (((a)->y) * ( (b)->z))) -                            \
         ( (((a)->z) * ( (b)->y))));                            \
    (o)->y =                                                    \
        (( (((a)->z) * ( (b)->x))) -                            \
         ( (((a)->x) * ( (b)->z))));                            \
    (o)->z =                                                    \
        (( (((a)->x) * ( (b)->y))) -                            \
         ( (((a)->y) * ( (b)->x))));                            \
}                                                               \
MACRO_STOP

#define _rwV3dNormalizeMacro(_result, _out, _in)                \
MACRO_START                                                     \
{                                                               \
    RwReal              length2 =                               \
        RwV3dDotProductMacro(_in, _in);                         \
                                                                \
    rwInvSqrtMacro(_result, length2);                           \
    RwV3dScaleMacro(_out, _in, _result);                        \
}                                                               \
MACRO_STOP

#define RwV3dNormalizeMacro(_result, _out, _in)                 \
MACRO_START                                                     \
{                                                               \
    RwReal              length2 =                               \
        RwV3dDotProductMacro((_in), (_in));                     \
    RwReal              recip ;                                 \
                                                                \
    rwSqrtInvSqrtMacro(_result,recip,length2);                  \
                                                                \
    RwV3dScaleMacro((_out), (_in), recip);                      \
}                                                               \
MACRO_STOP

#define RwV3dLengthMacro(_result, _in)                          \
MACRO_START                                                     \
{                                                               \
    (_result) = RwV3dDotProductMacro(_in, _in);                 \
    rwSqrtMacro(_result, _result);                              \
}                                                               \
MACRO_STOP

#if (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))

#define RwV2dAssign(o, a)               RwV2dAssignMacro(o, a)
#define RwV2dAdd(o, a, b)               RwV2dAddMacro(o, a, b)
#define RwV2dSub(o, a, b)               RwV2dSubMacro(o, a, b)
#define RwV2dLineNormal(_o, _a, _b)     RwV2dLineNormalMacro(_o, _a, _b)
#define RwV2dScale(o, i, s)             RwV2dScaleMacro(o, i, s)
#define RwV2dDotProduct(a,b)            RwV2dDotProductMacro(a,b)
#define RwV2dPerp(o, a)                 RwV2dPerpMacro(o, a)
#define RwV3dAssign(o, a)               RwV3dAssignMacro(o, a)
#define RwV3dAdd(o, a, b)               RwV3dAddMacro(o, a, b)
#define RwV3dSub(o, a, b)               RwV3dSubMacro(o, a, b)
#define RwV3dScale(o, a, s)             RwV3dScaleMacro(o, a, s)
#define RwV3dIncrementScaled(o, a, s)   RwV3dIncrementScaledMacro(o, a, s)
#define RwV3dNegate(o, a)               RwV3dNegateMacro(o, a)
#define RwV3dDotProduct(a, b)           RwV3dDotProductMacro(a, b)
#define RwV3dCrossProduct(o, a, b)      RwV3dCrossProductMacro(o, a, b)

#endif /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */

#define _rwRSqrt(_num)       (_rwSqrt(*(_num)))
#define _rwRInvSqrt(_num)    (_rwInvSqrt(*(_num)))

#define RWRAD2DEG(_x) ((_x) * (((RwReal)180)/(rwPI)))

#if (!defined(rw4OVERPISQ))
#define rw4OVERPISQ  ( ((RwReal)4) / ( rwPI * rwPI ))
#endif /* (!defined(rw4OVERPISQ)) */

#if (!defined(rwPI3))
#define rwPI3  (rwPI * (RwReal)3) 
#endif /* (!defined(rwPI3)) */

#if (!defined(rwPI3OVER2))
#define rwPI3OVER2  ( rwPI3 / (RwReal)2 )
#endif /* (!defined(rwPI3OVER2)) */

#if (!defined(rwPI3OVER8))
#define rwPI3OVER8  (rwPI3 / (RwReal)8 )
#endif /* (!defined(rwPI3OVER8)) */

#define RwQuadSin(_x)                                                \
    ( rw4OVERPISQ *                                                  \
      ( ( (_x) < 0 ) ?                                               \
        ( ( rwPI + (_x) ) * (_x) ) :                                 \
        ( ( rwPI - (_x) ) * (_x) ) ) )

#define RwQuadASin(_s)                                               \
    ( rwPIOVER2 * ( ((_s)<0) ?                                       \
                    ( _rwSqrt(((RwReal)1) + (_s)) - 1 ) :            \
                    ( 1 - _rwSqrt(((RwReal)1) - (_s)) ) )            \
      )

#define RwQuadCos(_x)                                                \
    ( rw4OVERPISQ *                                                  \
      ( ( (_x) < -rwPIOVER2 ) ?                                      \
        ( ( -rwPI3OVER2 - (_x) ) * ( -rwPIOVER2 - (_x) ) ) :         \
        ( ( (_x) < rwPIOVER2) ?                                      \
          ( ( rwPIOVER2 + (_x) ) * ( rwPIOVER2 - (_x) ) ) :          \
          ( ( rwPIOVER2 - (_x) ) * ( rwPI3OVER2 - (_x) ) ) ) ) )

#define RwQuadACos(_c)                                               \
    ( rwPIOVER2 * ( ((_c)<0) ?                                       \
                    (((RwReal)2) - _rwSqrt(((RwReal)1) + (_c))):     \
                    _rwSqrt(((RwReal)1)-(_c)))                       \
      )

#define RwQuadTan(_x)                                                \
    ( rwPI3 * (_x) / ( rwPI * rwPI - (_x) * (_x) * (RwReal)4 ) )

#define RwQuadATan(_t)                                               \
    ( ( _rwSqrt((rwPI3OVER8 * rwPI3OVER8) +                          \
                (_t) * (_t) * (rwPIOVER2 * rwPIOVER2) )              \
        - rwPI3OVER8 ) / ( _t)  )

#define RwQuadATan2(_s, _c)                                          \
    ( ( _rwSqrt((_c) * (_c) * (rwPI3OVER8 * rwPI3OVER8) +            \
                (_s) * (_s) * (rwPIOVER2 * rwPIOVER2) )              \
        - (_c) * rwPI3OVER8 ) / ( _s)  )

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif         /* __cplusplus */

/* Other useful stuff */

extern RwReal RwV3dNormalize(RwV3d * out, const RwV3d * in);
extern RwReal RwV3dLength(const RwV3d * in);

extern RwReal RwV2dLength(const RwV2d * in);
extern RwReal RwV2dNormalize(RwV2d * out, const RwV2d * in);

#if ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )

extern void RwV2dAssign(RwV2d * out,
                        const RwV2d * ina);
extern void RwV2dAdd(RwV2d * out,
                     const RwV2d * ina, const RwV2d * inb);
extern void RwV2dLineNormal(RwV2d * out,
                     const RwV2d * ina, const RwV2d * inb);
extern void RwV2dSub(RwV2d * out,
                     const RwV2d * ina, const RwV2d * inb);
extern void RwV2dPerp(RwV2d * out, const RwV2d * in);
extern void RwV2dScale(RwV2d * out,
                       const RwV2d * in, RwReal scalar);
extern RwReal RwV2dDotProduct(const RwV2d * ina, const RwV2d * inb);

extern void RwV3dAssign(RwV3d * out,
                        const RwV3d * ina);
extern void RwV3dAdd(RwV3d * out,
                     const RwV3d * ina, const RwV3d * inb);
extern void RwV3dSub(RwV3d * out,
                     const RwV3d * ina, const RwV3d * inb);
extern void RwV3dScale(RwV3d * out,
                       const RwV3d * in, RwReal scalar);
extern void RwV3dIncrementScaled(RwV3d * out, 
                                 const RwV3d * in, RwReal scalar);
extern void RwV3dNegate(RwV3d * out, const RwV3d * in);
extern RwReal RwV3dDotProduct(const RwV3d * ina, const RwV3d * inb);
extern void RwV3dCrossProduct(RwV3d * out,
                              const RwV3d * ina, const RwV3d * inb);

#endif         /* ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ) */

/* Transform points/vectors */
extern RwV3d *RwV3dTransformPoints(RwV3d * pointsOut,
                                   const RwV3d * pointsIn,
                                   RwInt32 numPoints,
                                   const RwMatrix * matrix);
extern RwV3d *RwV3dTransformVectors(RwV3d * vectorsOut,
                                    const RwV3d * vectorsIn,
                                    RwInt32 numPoints,
                                    const RwMatrix * matrix);

extern RwReal _rwSqrt(const RwReal num);
extern RwReal _rwInvSqrt(const RwReal num);

/* SPI */
extern RwReal _rwV3dNormalize(RwV3d * out, const RwV3d * in);

#ifdef    __cplusplus
}
#endif         /* __cplusplus */

/*
 * Backwards compatibility macros
 * Warning: repeated evaluation of first argument
 */

#define RwV3dTransformPoint(_point, _matrix)                    \
   RwV3dTransformPoints((_point), (_point), 1, (_matrix))

#define RwV3dTransformVector(_vector, _matrix)                  \
   RwV3dTransformVectors((_vector), (_vector), 1, (_matrix))

#define rwVectorOpen(instance, offset, size) \
       _rwVectorOpen(instance, offset, size)

#define rwVectorClose(instance, offset, size) \
       _rwVectorClose(instance, offset, size)

#define rwVectorSetMultFn(multPoint,multVector) \
       _rwVectorSetMultFn(multPoint,multVector)


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/sky2/pip2model.h ---*/

/**
 * \defgroup corep2sky2 PS2
 * \ingroup rwcorepowerpipe
 *
 * PS2
 */

/****************************************************************************
 Global Types
 */

/**
 * \ingroup corep2sky2
 * \typdef RxColorUnion
 * Typedef for an RxColorUnion union
 */
typedef union RxColorUnion RxColorUnion;
/**
 * \ingroup corep2sky2
 * \union RxColorUnion 
 * Union shared between immediate mode and retained mode object-space
 * vertices. Immediate mode vertices have vertex color whereas retained
 * mode vertices have preLitColor.
 */
union RxColorUnion
{
    RwRGBA              preLitColor;    /**< Vertex pre-lighting values */
    RwRGBA              color;          /**< Immediate mode vertex color */
};

/**
 * \ingroup corep2sky2
 * \typedef RxObjSpace3DVertex
 * Typedef for an RxObjSpace3DVertex structure
 */
typedef struct RxObjSpace3DVertex RxObjSpace3DVertex;
/**
 * \ingroup corep2sky2
 * \struct RxObjSpace3DVertex 
 * Structure representing an object space vertex
 */
struct RxObjSpace3DVertex
{
    RwV3d               objVertex;      /**< Object space vertex position */
    RxColorUnion        c;              /**< Object space color */ 
    RwV3d               objNormal;      /**< Object space normal */
    RwReal              u;              /**< Vertex tex coord */
    RwReal              v;              /**< Vertex tex coord */
};

/* The 3D immediate mode one is the same */
/**
 * \ingroup corep2sky2
 * \typedef RxObjSpace3DLitVertex
 * Typedef for an RxObjSpace3DLitVertex structure
 */
typedef RxObjSpace3DVertex RxObjSpace3DLitVertex;

/* This vertex format is non-truncatable */
#define RxObjSpace3DVertexNoUVsNoNormalsSize                \
    (offsetof(RxObjSpace3DVertex,objNormal))

#define RxObjSpace3DVertexNoUVsSize                         \
    (offsetof(RxObjSpace3DVertex,u))

#define RxObjSpace3DVertexFullSize                          \
    (sizeof(RxObjSpace3DVertex))

/* Defined in the driver: (eventually should be true of the above/below) */
/**
 * \ingroup corep2sky2
 * \typedef RxScrSpace2DVertex
 * Typedef for an RxScrSpace2DVertex structure
 */
typedef RwIm2DVertex RxScrSpace2DVertex;

/****************************************************************************
 Object-space 3D vertex macros
 */

#if defined (__MWERKS__)

#if (0 && ( __MWERKS__ >= 0x2401) )

#if (defined(RWVERBOSE))
#pragma message (__FILE__ "/" _SKY_EXPAND(__LINE__) ": __MWERKS__ == " _SKY_EXPAND(__MWERKS__))
#endif /* (defined(RWVERBOSE)) */

#define RxRGBAAssign(_target, _source)          \
MACRO_START                                     \
{                                               \
    RwRGBA * const dst = (_target);             \
    const RwRGBA * const src = (_source);       \
    dst->red = src->red;                        \
    dst->green = src->green;                    \
    dst->blue = src->blue;                      \
    dst->alpha = src->alpha;                    \
}                                               \
MACRO_STOP

#define RxV3dAssign(_target, _source)           \
MACRO_START                                     \
{                                               \
    RwV3d * const dst = (_target);              \
    const RwV3d * const src = (_source);        \
    dst->x = src->x;                            \
    dst->y = src->y;                            \
    dst->z = src->z;                            \
}                                               \
MACRO_STOP

#pragma message (__FILE__ "/" _SKY_EXPAND(__LINE__) ": Workarounds for __MWERKS__ == " _SKY_EXPAND(__MWERKS__))
#elif (defined(RWVERBOSE))
#pragma message (__FILE__ "/" _SKY_EXPAND(__LINE__) ": __MWERKS__ == " _SKY_EXPAND(__MWERKS__))

#endif /* (0 && ( __MWERKS__ >= 0x2401) ) */
#endif /* defined (__MWERKS__) */

#if (!defined(RxRGBAAssign))
#define RxRGBAAssign(_target, _source) RwRGBAAssign(_target, _source)
#endif /* (!defined(RxRGBAAssign)) */

#if (!defined(RxV3dAssign))
#define RxV3dAssign(_target, _source) RwV3dAssign(_target, _source)
#endif /* (!defined(RxV3dAssign)) */

/* Vertex positions */
#define RxObjSpace3DVertexGetPos(_vert, _pos)               \
    RxV3dAssign(_pos, &(_vert)->objVertex)

#define RxObjSpace3DVertexSetPos(_vert, _pos)               \
    RxV3dAssign(&(_vert)->objVertex, _pos)

/* Pre-lighting colours */
#define RxObjSpace3DVertexGetPreLitColor(_vert, _col)       \
    RxRGBAAssign(_col, &(_vert)->c.preLitColor)

#define RxObjSpace3DVertexSetPreLitColor(_vert, _col)       \
    RxRGBAAssign(&(_vert)->c.preLitColor, _col)

/* This uses the same slot as color (they are mutually exclusive) */
#define RxObjSpace3DVertexGetColor RxObjSpace3DVertexGetPreLitColor

/* Normals */
#define RxObjSpace3DVertexGetNormal(_vert, _normal)         \
    RxV3dAssign(_normal, &(_vert)->objNormal)

#define RxObjSpace3DVertexSetNormal(_vert, _normal)         \
    RxV3dAssign(&(_vert)->objNormal, _normal)

/* Us and Vs */
#define RxObjSpace3DVertexGetU(_vert)                       \
    ((_vert)->u)

#define RxObjSpace3DVertexGetV(_vert)                       \
    ((_vert)->v)

#define RxObjSpace3DVertexSetU(_vert, _imu)                 \
    ((_vert)->u = (_imu))

#define RxObjSpace3DVertexSetV(_vert, _imv)                 \
    ((_vert)->v = (_imv))

/**
 * \ingroup corep2sky2
 * \typedef RwIm3DVertex
 * Typedef for an RwIm3DVertex 
 */
typedef RxObjSpace3DLitVertex RwIm3DVertex;
/* LEGACY-SUPPORT macro */
#define RWIM3DVERTEX RwIm3DVertex

#define RwIm3DVertexSetU   RxObjSpace3DVertexSetU
#define RwIm3DVertexSetV   RxObjSpace3DVertexSetV
#define RwIm3DVertexGetNext(_vert)      ((_vert) + 1)

#define RwIm2DCameraVertexSetU(_devvert, _camvert, _u, _recipz) \
MACRO_START                                                     \
{                                                               \
    RwReal _uLocal = _u;                                        \
    _camvert->u = _uLocal;                                      \
    RwIm2DVertexSetU(_devvert, _uLocal, _recipz);               \
}                                                               \
MACRO_STOP

#define RwIm2DCameraVertexSetV(_devvert, _camvert, _v, _recipz) \
MACRO_START                                                     \
{                                                               \
    RwReal _vLocal = _v;                                        \
    _camvert->v = _vLocal;                                      \
    RwIm2DVertexSetV(_devvert, _vLocal, _recipz);               \
}                                                               \
MACRO_STOP

#define RwIm3DVertexSetPos(_vert, _imx, _imy, _imz)         \
MACRO_START                                                 \
{                                                           \
    RwV3d _packed;                                          \
    _packed.x = _imx;                                       \
    _packed.y = _imy;                                       \
    _packed.z = _imz;                                       \
    RxObjSpace3DVertexSetPos(_vert, &_packed);              \
}                                                           \
MACRO_STOP

#define RwIm3DVertexSetRGBA(_vert, _r, _g, _b, _a)          \
MACRO_START                                                 \
{                                                           \
    RwRGBA * const _col = &(_vert)->c.color;                \
    _col->red = (_r);                                       \
    _col->green = (_g);                                     \
    _col->blue = (_b);                                      \
    _col->alpha = (_a);                                     \
}                                                           \
MACRO_STOP

#define RwIm3DVertexSetNormal(_vert, _imx, _imy, _imz)      \
MACRO_START                                                 \
{                                                           \
    RwV3d _packed;                                          \
    _packed.x = _imx;                                       \
    _packed.y = _imy;                                       \
    _packed.z = _imz;                                       \
    RxObjSpace3DVertexSetNormal(_vert, &_packed);           \
}                                                           \
MACRO_STOP

#define RwIm3DVertexGetPos(_vert) (&((_vert)->objVertex))
#define RwIm3DVertexGetNormal(_vert) (&((_vert)->objNormal))

#define RwIm3DVertexCopyRGBA(dst,src)                       \
    RxRGBAAssign(&((dst)->c.color) , &((src)->c.color))

/* LEGACY-SUPPORT macros */
#define RWIM2DCAMERAVERTEXSetU(_devvert, _camvert, _u, _recipz) \
    RwIm2DCameraVertexSetU(_devvert, _camvert, _u, _recipz)
#define RWIM2DCAMERAVERTEXSetV(_devvert, _camvert, _v, _recipz) \
    RwIm2DCameraVertexSetV(_devvert, _camvert, _v, _recipz)
#define RWIM3DVERTEXGetNext(vert)               RwIm3DVertexGetNext(vert)
#define RWIM3DVERTEXSetPos(vert, imx, imy, imz) \
    RwIm3DVertexSetPos(vert, imx, imy, imz)
#define RWIM3DVERTEXGetPos(vert)                RwIm3DVertexGetPos(vert)
#define RWIM3DVERTEXSetU(vert, imu)             RwIm3DVertexSetU(vert, imu)
#define RWIM3DVERTEXSetV(vert, imv)             RwIm3DVertexSetV(vert, imv)
#define RWIM3DVERTEXSetRGBA(vert, r, g, b, a) \
    RwIm3DVertexSetRGBA(vert, r, g, b, a)
#define RWIM3DVERTEXSetNormal(vert, imx, imy, imz) \
    RwIm3DVertexSetNormal(vert, imx, imy, imz)
#define RWIM3DVERTEXCopyRGBA(dst,src)           RwIm3DVertexCopyRGBA(dst,src)
#define RXOBJSPACE3DVERTEXGetPos(_vert, _pos) \
    RxObjSpace3DVertexGetPos(_vert, _pos)
#define RXOBJSPACE3DVERTEXSetPos(_vert, _pos) \
    RxObjSpace3DVertexSetPos(_vert, _pos)
#define RXOBJSPACE3DVERTEXGetPreLitColor(_vert, _col) \
    RxObjSpace3DVertexGetPreLitColor(_vert, _col)
#define RXOBJSPACE3DVERTEXSetPreLitColor(_vert, _col) \
    RxObjSpace3DVertexSetPreLitColor(_vert, _col)
#define RXOBJSPACE3DVERTEXGetColor              RxObjSpace3DVertexGetColor
#define RXOBJSPACE3DVERTEXGetNormal(_vert, _normal) \
    RxObjSpace3DVertexGetNormal(_vert, _normal)
#define RXOBJSPACE3DVERTEXSetNormal(_vert, _normal) \
    RxObjSpace3DVertexSetNormal(_vert, _normal)
#define RXOBJSPACE3DVERTEXGetU(_vert)           RxObjSpace3DVertexGetU(_vert)
#define RXOBJSPACE3DVERTEXGetV(_vert)           RxObjSpace3DVertexGetV(_vert)
#define RXOBJSPACE3DVERTEXSetU(_vert, _imu) \
    RxObjSpace3DVertexSetU(_vert, _imu)
#define RXOBJSPACE3DVERTEXSetV(_vert, _imv) \
    RxObjSpace3DVertexSetV(_vert, _imv)


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2clpcom.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/baimmedi.h ---*/

/****************************************************************************
 Defines
 */


/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                        Immediate mode interface V2.0

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

/**
 * \ingroup datatypes
 * RwRenderState
 *     This type represents the various render states that
 * can be set using the API function \ref RwRenderStateSet. This function also
 * takes a render state value or pointer to an object depending on the type.
 * For render states that are toggles, the value should be TRUE to switch the
 * state on and FALSE to turn it off.
 *
 * Note that many of these render states may not be supported on certain
 * platforms. The \ref RwRenderStateSet functions will return FALSE in such cases.
 */
enum RwRenderState
{
    rwRENDERSTATENARENDERSTATE = 0,
    rwRENDERSTATETEXTURERASTER,             /**<Raster to texture with. \ref RwRenderStateSet
                                             *  takes a pointer to an \ref RwRaster */
    rwRENDERSTATETEXTUREADDRESS,            /**<\ref RwTextureAddressMode: wrap, clamp, mirror or border */
    rwRENDERSTATETEXTUREADDRESSU,           /**<\ref RwTextureAddressMode in u only */
    rwRENDERSTATETEXTUREADDRESSV,           /**<\ref RwTextureAddressMode in v only */
    rwRENDERSTATETEXTUREPERSPECTIVE,        /**<Perspective correction on/off */
    rwRENDERSTATEZTESTENABLE,               /**<Z-buffer test on/off */
    rwRENDERSTATESHADEMODE,                 /**<\ref RwShadeMode: flat or gouraud shading */
    rwRENDERSTATEZWRITEENABLE,              /**<Z-buffer write on/off */
    rwRENDERSTATETEXTUREFILTER,             /**<\ref RwTextureFilterMode: point sample, bilinear, trilinear, etc */
    rwRENDERSTATESRCBLEND,                  /**<Source alpha \ref RwBlendFunction: src alpha, 1-src alpha, etc */
    rwRENDERSTATEDESTBLEND,                 /**<Destination alpha \ref RwBlendFunction */
    rwRENDERSTATEVERTEXALPHAENABLE,         /**<Vertex alpha transparency on/off */
    rwRENDERSTATEBORDERCOLOR,               /**<Border color for \ref RwTextureAddressMode rwTEXTUREADDRESSBORDER.
                                             *  The value should be a packed RwUInt32 in ARGB form. The macro
                                             *  RWRGBALONG(r, g, b, a) may be used to construct this using 8-bit
                                             *  color components. */
    rwRENDERSTATEFOGENABLE,                 /**<Fogging on/off (all polygons will be fogged) */
    rwRENDERSTATEFOGCOLOR,                  /**<Color used for fogging. The value should be a packed RwUInt32
                                             *  in ARGB form. The macro RWRGBALONG(r, g, b, a) may be used to
                                             *  construct this using 8-bit color components */
    rwRENDERSTATEFOGTYPE,                   /**<Sets \ref RwFogType, the type of fogging to use */
    rwRENDERSTATEFOGDENSITY,                /**<Select the fog density for \ref RwFogType of rwFOGTYPEEXPONENTIAL
                                             *  or rwFOGTYPEEXPONENTIAL2. The value should be a pointer to
                                             *  an RwReal in the range 0 to 1. */
    rwRENDERSTATEFOGTABLE,                  /**<Install a 256 entry fog table placed between fog distance and far
                                             *  clip plane */
    rwRENDERSTATEALPHAPRIMITIVEBUFFER,      /**<Render transparent alpha polygons last - on/off */
    rwRENDERSTATECULLMODE,                  /**<Sets \ref RwCullMode, for selecting face culling. */
    rwRENDERSTATESTENCILENABLE,             /**< \if xbox
                                             *      TRUE to enable stenciling, or FALSE to disable stenciling
                                             *   \endif
                                             *   \if d3d8
                                             *      TRUE to enable stenciling, or FALSE to disable stenciling
                                             *   \endif
                                             */
    rwRENDERSTATESTENCILFAIL,               /**< \if xbox
                                             *      Stencil test operator for the fail case
                                             *   \endif
                                             *   \if d3d8
                                             *      Stencil test operator for the fail case
                                             *   \endif
                                             */
    rwRENDERSTATESTENCILZFAIL,              /**< \if xbox
                                             *      Stencil operation to perform if the stencil test passes
                                             *      and the depth test (z-test) fails
                                             *   \endif
                                             *   \if d3d8
                                             *      Stencil operation to perform if the stencil test passes
                                             *      and the depth test (z-test) fails
                                             *   \endif
                                             */
    rwRENDERSTATESTENCILPASS,               /**< \if xbox
                                             *      Stencil operation to perform if both the stencil and the 
                                             *      depth (z) tests pass
                                             *   \endif
                                             *   \if d3d8
                                             *      Stencil operation to perform if both the stencil and the 
                                             *      depth (z) tests pass
                                             *   \endif
                                             */
    rwRENDERSTATESTENCILFUNCTION,           /**< \if xbox
                                             *      Comparison function for the stencil test
                                             *   \endif
                                             *   \if d3d8
                                             *      Comparison function for the stencil test
                                             *   \endif
                                             */
    rwRENDERSTATESTENCILFUNCTIONREF,        /**< \if xbox
                                             *      Integer reference value for the stencil test
                                             *   \endif
                                             *   \if d3d8
                                             *      Integer reference value for the stencil test
                                             *   \endif
                                             */
    rwRENDERSTATESTENCILFUNCTIONMASK,       /**< \if xbox
                                             *      Mask applied to the reference value and each stencil buffer 
                                             *      entry to determine the significant bits for the stencil test
                                             *   \endif
                                             *   \if d3d8
                                             *      Mask applied to the reference value and each stencil buffer 
                                             *      entry to determine the significant bits for the stencil test
                                             *   \endif
                                             */
    rwRENDERSTATESTENCILFUNCTIONWRITEMASK,  /**< \if xbox
                                             *      Write mask applied to values written into the stencil buffer
                                             *   \endif
                                             *   \if d3d8
                                             *      Write mask applied to values written into the stencil buffer
                                             *   \endif
                                             */

    rwRENDERSTATEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwRenderState RwRenderState;


/**
 * \ingroup datatypes
 * RwShadeMode
 *  This type represents the options available for setting the
 * rwRENDERSTATESHADEMODE render state */
enum RwShadeMode
{
    rwSHADEMODENASHADEMODE = 0,     /**<Invalid shading mode */
    rwSHADEMODEFLAT,                /**<Flat shading */
    rwSHADEMODEGOURAUD,             /**<Gouraud shading */
    rwSHADEMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwShadeMode RwShadeMode;


/**
 * \ingroup datatypes
 * RwTextureFilterMode
 *  This type represents the options available for texture
 * filtering (see API functions \ref RwTextureSetFilterMode and \ref RwRenderStateSet)*/
enum RwTextureFilterMode
{
    rwFILTERNAFILTERMODE = 0,       /**<Invalid filter mode */
    rwFILTERNEAREST,                /**<Point sampled */
    rwFILTERLINEAR,                 /**<Bilinear */
    rwFILTERMIPNEAREST,             /**<Point sampled per pixel mip map */
    rwFILTERMIPLINEAR,              /**<Bilinear per pixel mipmap */
    rwFILTERLINEARMIPNEAREST,       /**<MipMap interp point sampled */
    rwFILTERLINEARMIPLINEAR,        /**<Trilinear */
    rwTEXTUREFILTERMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwTextureFilterMode RwTextureFilterMode;


/**
 * \ingroup datatypes
 * RwFogType
 *  This type represents the options available to the
 * rwRENDERSTATEFOGTYPE render state (see \ref RwRenderState);*/
enum RwFogType
{
    rwFOGTYPENAFOGTYPE = 0,     /**<Invalid fog type */
    rwFOGTYPELINEAR,            /**<Linear fog */
    rwFOGTYPEEXPONENTIAL,       /**<Exponential fog */
    rwFOGTYPEEXPONENTIAL2,      /**<Exponential^2 fog */
    rwFOGTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwFogType RwFogType;


/**
 * \ingroup datatypes
 * RwBlendFunction
 *  This type represents the options available
 * to the rwRENDERSTATESRCBLEND and rwRENDERSTATEDESTBLEND render states
 * (see \ref RwRenderState).  In the following description,
 * a subscript s refers to a source value while subscript d refers to a
 * destination value.*/
enum RwBlendFunction
{
    rwBLENDNABLEND = 0,     /**<Invalid blend mode */
    rwBLENDZERO,            /**<(0,    0,    0,    0   ) */
    rwBLENDONE,             /**<(1,    1,    1,    1   ) */
    rwBLENDSRCCOLOR,        /**<(Rs,   Gs,   Bs,   As  ) */
    rwBLENDINVSRCCOLOR,     /**<(1-Rs, 1-Gs, 1-Bs, 1-As) */
    rwBLENDSRCALPHA,        /**<(As,   As,   As,   As  ) */
    rwBLENDINVSRCALPHA,     /**<(1-As, 1-As, 1-As, 1-As) */
    rwBLENDDESTALPHA,       /**<(Ad,   Ad,   Ad,   Ad  ) */
    rwBLENDINVDESTALPHA,    /**<(1-Ad, 1-Ad, 1-Ad, 1-Ad) */
    rwBLENDDESTCOLOR,       /**<(Rd,   Gd,   Bd,   Ad  ) */
    rwBLENDINVDESTCOLOR,    /**<(1-Rd, 1-Gd, 1-Bd, 1-Ad) */
    rwBLENDSRCALPHASAT,     /**<(f,    f,    f,    1   )  f = min (As, 1-Ad) */
    rwBLENDFUNCTIONFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwBlendFunction RwBlendFunction;


/**
 * \ingroup datatypes
 * RwTextureAddressMode
 *  This type represents the options available for
 * applying textures to polygons (see API functions \ref RwTextureSetAddressing
 * and \ref RwRenderStateSet, and the \ref RwRenderState type) */
enum RwTextureAddressMode
{
    rwTEXTUREADDRESSNATEXTUREADDRESS = 0,   /**<Invalid addressing mode */
    rwTEXTUREADDRESSWRAP,                   /**<UV wraps (tiles) */
    rwTEXTUREADDRESSMIRROR,                 /**<Alternate UV is flipped */
    rwTEXTUREADDRESSCLAMP,                  /**<UV is clamped to 0-1 */
    rwTEXTUREADDRESSBORDER,                 /**<Border colour takes effect outside of 0-1 */
    rwTEXTUREADDRESSMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwTextureAddressMode RwTextureAddressMode;

enum RwStencilOperation
{
    rwSTENCILOPERATIONNASTENCILOPERATION = 0,
    rwSTENCILOPERATIONKEEP,     /* Do not update the entry in the stencil buffer */
    rwSTENCILOPERATIONZERO,     /* Set the stencil-buffer entry to 0 */
    rwSTENCILOPERATIONREPLACE,  /* Replace the stencil-buffer entry with reference value */
    rwSTENCILOPERATIONINCRSAT,  /* Increment the stencil-buffer entry, clamping to the maximum value */
    rwSTENCILOPERATIONDECRSAT,  /* Decrement the stencil-buffer entry, clamping to zero */    
    rwSTENCILOPERATIONINVERT,   /* Invert the bits in the stencil-buffer entry */
    rwSTENCILOPERATIONINCR,     /* Increment the stencil-buffer entry, wrapping to zero if the new value exceeds the maximum value */
    rwSTENCILOPERATIONDECR,     /* Decrement the stencil-buffer entry, wrapping to the maximum value if the new value is less than zero */
    rwSTENCILOPERATIONFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwStencilOperation RwStencilOperation;

enum RwStencilFunction
{
    rwSTENCILFUNCTIONNASTENCILFUNCTION = 0,
    rwSTENCILFUNCTIONNEVER,         /* Always fail the test */
    rwSTENCILFUNCTIONLESS,          /* Accept the new pixel if its value is less than the value of the current pixel */
    rwSTENCILFUNCTIONEQUAL,         /* Accept the new pixel if its value equals the value of the current pixel */
    rwSTENCILFUNCTIONLESSEQUAL,     /* Accept the new pixel if its value is less than or equal to the value of the current pixel */
    rwSTENCILFUNCTIONGREATER,       /* Accept the new pixel if its value is greater than the value of the current pixel */
    rwSTENCILFUNCTIONNOTEQUAL,      /* Accept the new pixel if its value does not equal the value of the current pixel */
    rwSTENCILFUNCTIONGREATEREQUAL,  /* Accept the new pixel if its value is greater than or equal to the value of the current pixel */
    rwSTENCILFUNCTIONALWAYS,        /* Always pass the test */
    rwSTENCILFUNCTIONFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwStencilFunction RwStencilFunction;

/**
 * \ingroup datatypes
 * RwCullMode
 *  This type represents the options available for culling polygons during rendering.
 * and \ref RwRenderStateSet, and the \ref RwRenderState type) */
enum RwCullMode
{
    rwCULLMODENACULLMODE = 0,
    rwCULLMODECULLNONE,                /**< Both front and back-facing triangles are drawn. */
    rwCULLMODECULLBACK,                /**< Just front-facing triangles are drawn */
    rwCULLMODECULLFRONT,               /**< Just rear-facing triangles are drawn */

    rwCULLMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwCullMode RwCullMode;

/**
 * \ingroup datatypes
 * RwPrimitiveType
 *  This type represents the different types of indexed
 * line and indexed triangle primitives that are available when rendering 2D
 * and 3D immediate mode objects (see API functions \ref RwIm2DRenderIndexedPrimitive,
 * \ref RwIm2DRenderPrimitive, \ref RwIm3DRenderIndexedPrimitive and \ref RwIm3DRenderPrimitive).
 * Indices are into a vertex list and must be defined in a counter-clockwise order
 * (as seen from the camera) to be visible.*/
enum RwPrimitiveType
{
    rwPRIMTYPENAPRIMTYPE = 0,   /**<Invalid primative type */
    rwPRIMTYPELINELIST = 1,     /**<Unconnected line segments, each line is specified by
                                 * both its start and end index, independently of other lines
                                 * (for example, 3 segments specified as 0-1, 2-3, 4-5) */
    rwPRIMTYPEPOLYLINE = 2,     /**<Connected line segments, each line's start index
                                 * (except the first) is specified by the index of the end of
                                 * the previous segment (for example, 3 segments specified as
                                 * 0-1, 1-2, 2-3) */
    rwPRIMTYPETRILIST = 3,      /**<Unconnected triangles: each triangle is specified by
                                 * three indices, independently of other triangles (for example,
                                 * 3 triangles specified as 0-1-2, 3-4-5, 6-7-8) */
    rwPRIMTYPETRISTRIP = 4,     /**<Connected triangles sharing an edge with, at most, one
                                 * other forming a series (for example, 3 triangles specified
                                 * as 0-2-1, 1-2-3-, 2-4-3) */
    rwPRIMTYPETRIFAN = 5 ,      /**<Connected triangles sharing an edge with, at most,
                                 * two others forming a fan (for example, 3 triangles specified
                                 * as 0-2-1, 0-3-2, 0-4-3) */
    rwPRIMTYPEPOINTLIST = 6,    /**<Points 1, 2, 3, etc. This is not
                                 * supported by the default RenderWare
                                 * immediate or retained-mode pipelines
                                 * (except on PlayStation 2), it is intended
                                 * for use by user-created pipelines */
    rwPRIMITIVETYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwPrimitiveType RwPrimitiveType;




/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Expose Z buffer range */
extern RwReal RwIm2DGetNearScreenZ(void);
extern RwReal RwIm2DGetFarScreenZ(void);

extern RwBool RwRenderStateGet(RwRenderState state, void *value);
extern RwBool RwRenderStateSet(RwRenderState state, void *value);

extern RwBool RwIm2DRenderLine(RwIm2DVertex *vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2);
extern RwBool RwIm2DRenderTriangle(RwIm2DVertex *vertices, RwInt32 numVertices,
                                   RwInt32 vert1, RwInt32 vert2, RwInt32 vert3 );
extern RwBool RwIm2DRenderPrimitive(RwPrimitiveType primType, RwIm2DVertex *vertices, RwInt32 numVertices);
extern RwBool RwIm2DRenderIndexedPrimitive(RwPrimitiveType primType, RwIm2DVertex *vertices, RwInt32 numVertices,
                                                             RwImVertexIndex *indices, RwInt32 numIndices);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/baim3doc.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2renderstate.h ---*/

/**
 * \ingroup rwcoregeneric
 *  RxRenderStateFlag 
 *  Flags used in the \ref RxRenderStateVector structure */
enum RxRenderStateFlag
{
    rxRENDERSTATEFLAG_TEXTUREPERSPECTIVE   = 0x00000001, /**<Perspective texturing is to be enabled */
    rxRENDERSTATEFLAG_ZTESTENABLE          = 0x00000002, /**<Z-Buffer testing is to be performed */
    rxRENDERSTATEFLAG_ZWRITEENABLE         = 0x00000004, /**<Z-Buffer writing is to be enabled */
    rxRENDERSTATEFLAG_VERTEXALPHAENABLE    = 0x00000008, /**<Vertex alpha is to be enabled */
    rxRENDERSTATEFLAG_FOGENABLE            = 0x00000010, /**<Fog is to be enabled */
    rxRENDERSTATEFLAG_ALPHAPRIMITIVEBUFFER = 0x00000020, /**<Alpha primitive buffering is to be enabled */
    rxRENDERSTATEFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RxRenderStateFlag RxRenderStateFlag;

typedef struct RxRenderStateVector RxRenderStateVector;
/**
 * \ingroup rwcoregeneric
 * \struct RxRenderStateVector
 * Structure describing a render-state vector,
 * used by the RxClRenderState cluster */
struct RxRenderStateVector
{
    RwUInt32             Flags;         /**< A load of the boolean renderstate options */
    RwShadeMode          ShadeMode;     /**< Flat or Gouraud currently */
    RwBlendFunction      SrcBlend;      /**< Src  alpha, 1-src  alpha, etc */
    RwBlendFunction      DestBlend;     /**< Dest alpha, 1-dest alpha, etc */
    RwRaster            *TextureRaster; /**< texture raster */
    RwTextureAddressMode AddressModeU;  /**< U addressing mode - WRAP, MIRROR, CLAMP, BORDER */
    RwTextureAddressMode AddressModeV;  /**< V addressing mode - WRAP, MIRROR, CLAMP, BORDER */
    RwTextureFilterMode  FilterMode;    /**< filtering mode - combos of NEAREST LINEAR MIP */
    RwRGBA               BorderColor;   /**< Border color for texturing address mode border */
    RwFogType            FogType;       /**< Select the type of fogging to use */
    RwRGBA               FogColor;      /**< Color used for fogging */
    RwUInt8             *FogTable;      /**< A 256 entry fog table */
};

#if (!defined(RxRenderStateVectorAssign))
#define RxRenderStateVectorAssign(_target, _source)            \
    ( *(_target) = *(_source) )
#endif /* (!defined(RxRenderStateVectorAssign)) */



#ifdef    __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern       RxRenderStateVector *RxRenderStateVectorSetDefaultRenderStateVector(RxRenderStateVector *rsvp);
extern const RxRenderStateVector *RxRenderStateVectorGetDefaultRenderStateVector(void);
extern       RxRenderStateVector *RxRenderStateVectorCreate(RwBool current);
extern       void                 RxRenderStateVectorDestroy(RxRenderStateVector *rsvp);
extern       RxRenderStateVector *RxRenderStateVectorLoadDriverState(RxRenderStateVector *rsvp);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeRGBAInterp.h ---*/

struct NodeRGBAInterpData
{
    RwBool              rgbaInterpOn;
    RxRenderStateVector state;
};
typedef struct NodeRGBAInterpData NodeRGBAInterpData;


#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition *RxNodeDefinitionGetRGBAInterp(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/nodeUVInterp.h ---*/

typedef struct RxNodeUVInterpSettings RxNodeUVInterpSettings;
struct RxNodeUVInterpSettings
{
    RwBool              uvInterpOn;
    RxRenderStateVector state;
};


#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition * RxNodeDefinitionGetUVInterp(void);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/baimage.h ---*/

/****************************************************************************
 Defines
 */

/* If this bit is set then the image has been allocated by the user */

enum RwImageFlag
{
    rwNAIMAGEFLAG = 0x00,
    rwIMAGEALLOCATED = 0x1,
    rwIMAGEGAMMACORRECTED = 0x2,
    rwIMAGEFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwImageFlag RwImageFlag;

/****************************************************************************
 Global Types
 */

/**
 * \ingroup datatypes
 * \typedef RwImage 
 * Image containing device-independent pixels. 
 * This should be considered an opaque type.
 * Use the RwImage API functions to access.
 */
typedef struct RwImage RwImage;

#if (!defined(DOXYGEN))
struct RwImage
{
        RwInt32             flags;

        RwInt32             width;  /* Device may have different ideas */
        RwInt32             height; /* internally !! */

        RwInt32             depth;  /* Of referenced image */
        RwInt32             stride;

        RwUInt8            *cpPixels;
        RwRGBA             *palette;
};
#endif /* (!defined(DOXYGEN)) */

/**
 * \ingroup datatypes
 * \ref RwImageCallBackRead 
 * is the function registered with \ref RwImageRegisterImageFormat that is used,
 * for example by \ref RwImageRead and \ref RwImageReadMaskedImage,
 * to read images of a specific format from a disk file.
 * 
 * \param  imageName   Pointer to a string containing the file name of the image.
 *
 * \see RwImageRegisterImageFormat
 *
 */
typedef RwImage *(*RwImageCallBackRead)(const RwChar * imageName);

/**
 * \ingroup datatypes
 * \ref RwImageCallBackWrite 
 * is the function registered with \ref RwImageRegisterImageFormat that is used,
 * for example by \ref RwImageWrite, 
 * to write images of a specific format to a disk file.
 * 
 * \param  image   Pointer to the image.
 *
 * \param  imageName   Pointer to a string containing the file name
 * of the image.
 *
 *
 * \return Pointer to the written image.
 *
 * \see RwImageRegisterImageFormat
 *
 */
typedef RwImage *(*RwImageCallBackWrite)(RwImage *image, const RwChar *imageName);


#define RwImageGetStrideMacro(_image) \
   ((_image)->stride)

#if (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))

#define RwImageGetStride(_image)        RwImageGetStrideMacro(_image)

#endif /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

    /* Creating and destroying */
extern RwImage     *RwImageCreate(RwInt32 width, RwInt32 height,
                                  RwInt32 depth);
extern RwBool       RwImageDestroy(RwImage * image);

    /* Allocating */
extern RwImage     *RwImageAllocatePixels(RwImage * image);
extern RwImage     *RwImageFreePixels(RwImage * image);

    /* Converting images */
extern RwImage     *RwImageCopy(RwImage * destImage,
                                const RwImage * sourceImage);

    /* Resizing images */
extern RwImage     *RwImageResize(RwImage * image, RwInt32 width,
                                  RwInt32 height);

    /* Producing masks ! */
extern RwImage     *RwImageApplyMask(RwImage * image,
                                     const RwImage * mask);
extern RwImage     *RwImageMakeMask(RwImage * image);

    /* Helper functions */
extern RwImage     *RwImageReadMaskedImage(const RwChar * imageName,
                                           const RwChar * maskname);
extern RwImage     *RwImageRead(const RwChar * imageName);
extern RwImage     *RwImageWrite(RwImage * image,
                                 const RwChar * imageName);

    /* Setting and getting the default path for images */
extern RwChar      *RwImageGetPath(void);
extern const RwChar *RwImageSetPath(const RwChar * path);

    /* Setting */
extern RwImage     *RwImageSetStride(RwImage * image, RwInt32 stride);
extern RwImage     *RwImageSetPixels(RwImage * image, RwUInt8 * pixels);
extern RwImage     *RwImageSetPalette(RwImage * image, RwRGBA * palette);

    /* Getting */
extern RwInt32      RwImageGetWidth(const RwImage * image);
extern RwInt32      RwImageGetHeight(const RwImage * image);
extern RwInt32      RwImageGetDepth(const RwImage * image);
extern RwUInt8     *RwImageGetPixels(const RwImage * image);
extern RwRGBA      *RwImageGetPalette(const RwImage * image);

    /* Get device dependent pixel value */
extern RwInt32      RwRGBAToPixel(RwRGBA * rgbIn, RwInt32 rasterFormat);
extern RwRGBA      *RwRGBASetFromPixel(RwRGBA * rgbOut,
                                       RwInt32 pixelValue,
                                       RwInt32 rasterFormat);

    /* Gamma correction */
extern RwBool       RwImageSetGamma(RwReal gammaValue);
extern RwReal       RwImageGetGamma(void);
extern RwImage     *RwImageGammaCorrect(RwImage * image);

    /* Adding and removing gamma correction */
extern RwRGBA      *RwRGBAGammaCorrect(RwRGBA * rgb);

    /* Attaching toolkits */
extern RwInt32      RwImageRegisterPlugin(RwInt32 size, RwUInt32 pluginID,
                                          RwPluginObjectConstructor
                                          constructCB,
                                          RwPluginObjectDestructor
                                          destructCB,
                                          RwPluginObjectCopy copyCB);
extern RwInt32      RwImageGetPluginOffset(RwUInt32 pluginID);
extern RwBool       RwImageValidatePlugins(const RwImage * image);

extern RwBool       RwImageRegisterImageFormat(const RwChar * extension,
                                               RwImageCallBackRead
                                               imageRead,
                                               RwImageCallBackWrite
                                               imageWrite);

    /* Finding an extension for an image to load */
extern const RwChar *RwImageFindFileType(const RwChar * imageName);

    /* Reading and writing images to streams */
extern RwInt32      RwImageStreamGetSize(const RwImage * image);
extern RwImage     *RwImageStreamRead(RwStream * stream);
extern const RwImage *RwImageStreamWrite(const RwImage * image,
                                         RwStream * stream);


#if ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )

extern RwInt32      RwImageGetStride(const RwImage * image);

#endif                          /* ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ) */

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/*--- Automatically derived from: E:/nightly/rwsdk/src/batextur.h ---*/

/****************************************************************************
 Defines
 */

/* Type ID */
#define rwTEXDICTIONARY 6

/* Mipmap Name generation - maximum number of RwChar characters which can
 * be appended to the root name.
 */
#define rwTEXTUREMIPMAPNAMECHARS    16

/* We define texture names to be a maximum of 16 ISO chars */
#define rwTEXTUREBASENAMELENGTH     32

/****************************************************************************
 Global Types
 */

/**
 * \ingroup datatypes
 * \typedef RwTexDictionary 
 * is a texture dictionary containing textures. 
 * This should be considered an opaque type.
 * Use the RwTexDictionary API functions to access.
 */
typedef struct RwTexDictionary RwTexDictionary;

#if (!defined(DOXYGEN))
struct RwTexDictionary
{
    RwObject            object; /* Homogeneous type */
    RwLinkList          texturesInDict; /* List of textures in dictionary */
    RwLLLink            lInInstance; /* Link list of all dicts in system */
};
/* Information is entirely device dependent */
#endif /* (!defined(DOXYGEN)) */


/* Parent is the dictionary */

/**
 * \ingroup datatypes
 * \typedef  RwTexture 
 * is a texture object. 
 * This should be considered an opaque type.
 * Use the RwTexture API functions to access.
 */
typedef struct RwTexture RwTexture;

#if (!defined(DOXYGEN))
struct RwTexture
{
    RwRaster           *raster; /** pointer to RwRaster with data */
    RwTexDictionary    *dict;   /* Dictionary this texture is in */
    RwLLLink            lInDictionary; /* List of textures in this dictionary */

    RwChar              name[rwTEXTUREBASENAMELENGTH];  /* Name of the texture */
    RwChar              mask[rwTEXTUREBASENAMELENGTH];  /* Name of the textures mask */

    RwInt32             refCount; /* Reference count, surprisingly enough */

    RwTextureFilterMode filtering; /* Texture filtering mode used */
    RwTextureAddressMode addressingU; /* Texture address mode used */
    RwTextureAddressMode addressingV; /* Texture address mode used */
};
#endif /* (!defined(DOXYGEN)) */

/**
 * \ingroup datatypes
 * \ref RwTextureCallBackRead 
 * represents the function used by \ref RwTextureRead to read the specified
 * texture from a disk file. This function should return a pointer to the
 * texture to indicate success.
 * 
 * \param  name   Pointer to a string containing the name of
 * the texture to read.
 *
 * \param  maskName   Pointer to a string containing the name
 * of the mask to read and apply to the texture.
 *
 * \return Pointer to the texture
 *
 * \see RwTextureSetReadCallBack
 * \see RwTextureGetReadCallBack
 */
typedef RwTexture *(*RwTextureCallBackRead)(const RwChar *name,
                                            const RwChar *maskName);

/**
 * \ingroup datatypes
 * \ref RwTextureCallBack
 * represents the function called from \ref RwTexDictionaryForAllTextures
 * for all textures in a given texture dictionary. This function should
 * return the current texture to indicate success. The callback may return
 * NULL to terminate further callbacks on the texture dictionary.
 * 
 * \param  texture   Pointer to the current texture.
 *
 * \param  pData   User-defined data pointer.
 *
 * \return Pointer to the current texture
 *
 * \see RwTexDictionaryForAllTextures
 */
typedef RwTexture *(*RwTextureCallBack)(RwTexture *texture, void *pData);


/**
 * \ingroup datatypes
 * \ref RwTexDictionaryCallBack
 * represents the function called from \ref RwTexDictionaryForAllTexDictionaries
 * for all texture dictionaries that currently exist. This function should
 * return the current texture dictionary to indicate success. The callback may
 * return NULL to terminate further callbacks on the texture dictionary. It may
 * safely destroy the current texture dictionary without adversely affecting
 * the iteration process.
 * 
 * \param  dict   Pointer to the current texture dictionary.
 *
 * \param  pData   User-defined data pointer.
 *
 * \return Pointer to the current texture dictionary
 *
 * \see RwTexDictionaryForAllTexdictionaries
 */
typedef RwTexDictionary *(*RwTexDictionaryCallBack)(RwTexDictionary *dict, void *data);


/**
 * \ingroup datatypes
 * \ref RwTextureCallBackMipmapGeneration 
 * is the callback function supplied to \ref RwTextureSetMipmapGenerationCallBack 
 * and returned from \ref RwTextureGetMipmapGenerationCallBack.
 *
 * The supplied function will be passed a pointer to a raster and an image.
 * The raster is the target for the generated mipmap levels and the image 
 * provides the base for their generation.
 * 
 * \param  raster   Pointer to raster, the target for generated mipmap levels
 * \param  image    Pointer to image, used to generate mipmap levels.
 * 
 * \return
 * Returns a pointer to the raster if successful or NULL if an error occurred.
 * 
 * \see RwTextureSetMipmapGenerationCallBack
 * \see RwTextureGetMipmapGenerationCallBack
 * \see RwTextureSetAutoMipmapping
 * \see RwTextureGetAutoMipmapping
 */
typedef RwRaster *(*RwTextureCallBackMipmapGeneration)(RwRaster * raster,
                                                       RwImage * image);

/**
 * \ingroup datatypes
 * \ref RwTextureCallBackMipmapName
 * is the callback function supplied to \ref RwTextureSetMipmapNameCallBack and
 * returned from \ref RwTextureGetMipmapNameCallBack.
 *
 * The supplied function will be passed a pointer to a root name, a maskName, a mipmap
 * level and a format. The function returns TRUE if successful and the root name will have been 
 * modified to equal the mipmap name.
 * 
 * \param  name       Pointer to a string containing the root name of the texture. The 
 * mipmap level name is put here.
 * \param  maskName   Pointer to a string containing the root mask name of the texture or
 * NULL if no mask name is required.
 * \param  mipLevel   A value equal to the mipmap level for which the name is required.
 * \param  format     A value describing the mipmapping mode. A combination of the bit
 * flags rwRASTERFORMATMIPMAP and rwRASTERFORMATAUTOMIPMAP.
 * 
 * \return
 * Returns TRUE if the name is generated successfully or FALSE if an error occurred.
 * 
 * \see RwTextureGenerateMipmapName
 * \see RwTextureSetMipmapNameCallBack
 * \see RwTextureGetMipmapNameCallBack
 * \see RwTextureSetAutoMipmapping
 * \see RwTextureGetAutoMipmapping
 */
typedef RwBool (*RwTextureCallBackMipmapName)(RwChar *name,
                                              RwChar *maskName,
                                              RwUInt8 mipLevel,
                                              RwInt32 format);

/* macros used in release builds */
#define RwTextureGetRasterMacro(_tex)           ((_tex)->raster)
#define RwTextureGetFilterModeMacro(_tex)       ((_tex)->filtering)
#define RwTextureGetAddressingUMacro(_tex)      ((_tex)->addressingU)
#define RwTextureGetAddressingVMacro(_tex)      ((_tex)->addressingV)
#define RwTextureGetAddressingMacro(_tex) \
    ((((_tex)->addressingU) == ((_tex)->addressingV)) ? (_tex)->addressingU : \
    rwTEXTUREADDRESSNATEXTUREADDRESS)


#if (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))

#define RwTextureGetRaster(tex)         RwTextureGetRasterMacro(tex)
#define RwTextureGetFilterMode(tex)     RwTextureGetFilterModeMacro(tex)
#define RwTextureGetAddressing(tex)     RwTextureGetAddressingMacro(tex)
#define RwTextureGetAddressingU(tex)    RwTextureGetAddressingUMacro(tex)
#define RwTextureGetAddressingV(tex)    RwTextureGetAddressingVMacro(tex)

#endif


/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

    /* Reading mip maps */

    /* Setting mip mapping states */
extern RwBool       RwTextureSetMipmapping(RwBool enable);
extern RwBool       RwTextureGetMipmapping(void);
extern RwBool       RwTextureSetAutoMipmapping(RwBool enable);
extern RwBool       RwTextureGetAutoMipmapping(void);

    /* Setting and getting the mipmap generation function */
extern              RwBool
RwTextureSetMipmapGenerationCallBack(RwTextureCallBackMipmapGeneration
                                     callback);
extern              RwTextureCallBackMipmapGeneration
RwTextureGetMipmapGenerationCallBack(void);

    /* Setting and getting the mipmap file name generation function */
extern              RwBool
RwTextureSetMipmapNameCallBack(RwTextureCallBackMipmapName callback);
extern RwTextureCallBackMipmapName RwTextureGetMipmapNameCallBack(void);

    /* Generating mipmaps for a raster */
extern RwBool       RwTextureGenerateMipmapName(RwChar * name,
                                                RwChar * maskName,
                                                RwUInt8 mipLevel,
                                                RwInt32 format);
extern RwBool       RwTextureRasterGenerateMipmaps(RwRaster * raster,
                                                   RwImage * image);

    /* LEGACY-SUPPORT mip mapping */
extern RwBool       _rwTextureSetAutoMipMapState(RwBool enable);
extern RwBool       _rwTextureGetAutoMipMapState(void);

    /* Setting and getting the callback function */
extern RwTextureCallBackRead RwTextureGetReadCallBack(void);
extern RwBool       RwTextureSetReadCallBack(RwTextureCallBackRead
                                             fpCallBack);

    /* Texture and mask names */
extern RwChar      *RwTextureGetName(RwTexture * texture);
extern RwChar      *RwTextureGetMaskName(RwTexture * texture);
extern RwTexture   *RwTextureSetName(RwTexture * texture,
                                     const RwChar * name);
extern RwTexture   *RwTextureSetMaskName(RwTexture * texture,
                                         const RwChar * maskName);

    /* Creating/destroying dictionaries */
extern RwTexDictionary *RwTexDictionaryCreate(void);
extern RwBool       RwTexDictionaryDestroy(RwTexDictionary * dict);

    /* Textures */
extern RwTexture   *RwTextureCreate(RwRaster * raster);
extern RwTexture   *RwTextureAddRef(RwTexture * texture);
extern RwBool       RwTextureDestroy(RwTexture * texture);

    /* Setting and getting texture map rasters */
extern RwTexture   *RwTextureSetRaster(RwTexture * texture,
                                       RwRaster * raster);
#if ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )
extern RwRaster    *RwTextureGetRaster(const RwTexture * texture);
#endif

    /* Filtering */
extern RwTexture   *RwTextureSetFilterMode(RwTexture * texture,
                                           RwTextureFilterMode filtering);
#if ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )
extern RwTextureFilterMode RwTextureGetFilterMode(const RwTexture *
                                                  texture);
#endif

    /* Addressing */
extern RwTexture *RwTextureSetAddressing(RwTexture *texture,
                                         RwTextureAddressMode
                                         addressing);
extern RwTexture *RwTextureSetAddressingU(RwTexture *texture,
                                          RwTextureAddressMode
                                          addressing);
extern RwTexture *RwTextureSetAddressingV(RwTexture *texture,
                                          RwTextureAddressMode
                                          addressing);
#if ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )
extern RwTextureAddressMode RwTextureGetAddressing(const RwTexture *texture);
extern RwTextureAddressMode RwTextureGetAddressingU(const RwTexture *texture);
extern RwTextureAddressMode RwTextureGetAddressingV(const RwTexture *texture);
#endif

    /* Dictionary access */
extern RwTexture   *RwTexDictionaryAddTexture(RwTexDictionary * dict,
                                              RwTexture * texture);
extern RwTexture   *RwTexDictionaryRemoveTexture(RwTexture * texture);
extern RwTexture   *RwTexDictionaryFindNamedTexture(RwTexDictionary *
                                                    dict,
                                                    const RwChar * name);

    /* Reading a texture */
extern RwTexture   *RwTextureRead(const RwChar * name,
                                  const RwChar * maskName);

    /* Setting the current dictionary */
extern RwTexDictionary *RwTexDictionaryGetCurrent(void);
extern RwTexDictionary *RwTexDictionarySetCurrent(RwTexDictionary * dict);

    /* Get owner dictionary */
extern RwTexDictionary *RwTextureGetDictionary(RwTexture * texture);

    /* Enumerating textures */
extern const RwTexDictionary *RwTexDictionaryForAllTextures(const
                                                            RwTexDictionary
                                                            * dict,
                                                            RwTextureCallBack
                                                            fpCallBack,
                                                            void *pData);

    /* Enumerating the texture dictionaries currently in the system */
extern RwBool RwTexDictionaryForAllTexDictionaries(
    RwTexDictionaryCallBack fpCallBack, void *pData);


    /* Attaching toolkits */
extern RwInt32      RwTextureRegisterPlugin(RwInt32 size,
                                            RwUInt32 pluginID,
                                            RwPluginObjectConstructor
                                            constructCB,
                                            RwPluginObjectDestructor
                                            destructCB,
                                            RwPluginObjectCopy copyCB);
extern RwInt32      RwTexDictionaryRegisterPlugin(RwInt32 size,
                                                  RwUInt32 pluginID,
                                                  RwPluginObjectConstructor
                                                  constructCB,
                                                  RwPluginObjectDestructor
                                                  destructCB,
                                                  RwPluginObjectCopy
                                                  copyCB);
extern RwInt32      RwTextureGetPluginOffset(RwUInt32 pluginID);
extern RwInt32      RwTexDictionaryGetPluginOffset(RwUInt32 pluginID);
extern RwBool       RwTextureValidatePlugins(const RwTexture * texture);
extern RwBool       RwTexDictionaryValidatePlugins(const RwTexDictionary *
                                                   dict);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

#define RwTextureSetAutoMipMapState(_enable) \
    _rwTextureSetAutoMipMapState(_enable)

#define RwTextureGetAutoMipMapState() \
    _rwTextureGetAutoMipMapState()


/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/drvfns.h ---*/

enum RpSkyRenderState
{
    rpSKYRENDERSTATENARENDERSTATE = 0,
    rpSKYRENDERSTATEDITHER, /**< 0=off, 0x55555555=half, else on */
    rpSKYRENDERSTATEALPHA_1,    /**< ALPHA_1 register with FIX in bits 24-31*/
                                /* Allows us to pass a constant in rather */
                                /* than a pointer to a long */
    rpSKYRENDERSTATEATEST_1, /**< Bottom 16 bits of TEST_1 register */
    rpSKYRENDERSTATEFARFOGPLANE, /**< Specify the Maximum Fog Distance */
    rpSKYRENDERSTATEMAXMIPLEVELS, /**< Max number of mip levels rasters are 
                                   *  created with. Must be <= 7. 
                                   *  Mip levels are still only created 
                                   *  if >8 texels in both dimensions. */
    rpSKYRENDERSTATEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RpSkyRenderState RpSkyRenderState;

/****************************************************************************
 Function prototypes
 */
#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

#define RwSkyInitWorldPipeline() (TRUE)

extern RwBool RpSkySelectDeepZBuffer(RwBool val);

extern RwReal RpSkyTextureSetDefaultMipmapK(RwReal val);
extern RwUInt32 RpSkyTextureSetDefaultMipmapL(RwUInt32 val);
extern RwReal RpSkyTextureGetDefaultMipmapK(void);
extern RwUInt32 RpSkyTextureGetDefaultMipmapL(void);
extern RwTexture *RpSkyTextureSetMipmapK(RwTexture *tex, RwReal val);
extern RwTexture *RpSkyTextureSetMipmapL(RwTexture *tex, RwUInt32 val);
extern RwReal RpSkyTextureGetMipmapK(RwTexture *tex);
extern RwUInt32 RpSkyTextureGetMipmapL(RwTexture *tex);

extern RwBool RpSkyTextureCacheSetState(RwInt32 nFlags);

extern RwBool RpSkySelectTrueTSClipper(RwBool val);
extern RwBool RpSkyGetTrueTSClipper(void);

extern RwBool RpSkySelectTrueTLClipper(RwBool val);
extern RwBool RpSkyGetTrueTLClipper(void);

extern RwBool RpSkyRenderStateSet(RpSkyRenderState nState, void *pParam);
extern RwBool RpSkyRenderStateGet(RpSkyRenderState nState, void *pParam);

extern RwRaster *	RpSkyGetDisplayBufferRaster(void);
extern RwRaster *	RpSkyGetDrawBufferRaster(void);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/p2stdcls.h ---*/

/*
 * Current:
 *
 * wait on Simon for instructions to do cluster renaming thing,
 * or go thru and  change all cluster type names and cluster
 * names (add CSL?)
 *
 */

/* CamVerts.csl */

/* clip flags */

/**
 * \ingroup rwcoregeneric
 * \ref RwClipFlag
 * Flags specifying the clipping status of a vertex
 */
enum RwClipFlag
{
    rwXLOCLIP   = 0x01, /**<The vertex is outside the low X clip plane */
    rwXHICLIP   = 0x02, /**<The vertex is outside the high X clip plane */
    rwXCLIP     = 0x03, /**<The vertex is outside an X clip plane */

    rwYLOCLIP   = 0x04, /**<The vertex is outside the low Y clip plane */
    rwYHICLIP   = 0x08, /**<The vertex is outside the high Z clip plane */
    rwYCLIP     = 0x0C, /**<The vertex is outside a Y clip plane */

    rwZLOCLIP   = 0x10, /**<The vertex is outside the low Z clip plane */
    rwZHICLIP   = 0x20, /**<The vertex is outside the high Z clip plane */
    rwZCLIP     = 0x30, /**<The vertex is outside a Z clip plane */

    rwCLIPMASK  = 0x3F, /**<Mask covering all used bits in the clip flags
                         * in case a plugin  wants free ones to use (e.g RpGloss) */

    rwCLIPFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwClipFlag RwClipFlag;

/**
 * \ingroup rwcoregeneric
 * \typedef RwClipFlag
 * Typedef for RwClipFlag enumeration specifying the clipping status of a vertex
 */


typedef struct RxCamSpace3DVertex RxCamSpace3DVertex;

/**
 * \ingroup rwcoregeneric
 * \struct RxCamSpace3DVertex
 * Structure describing a camera-space 3D vertex.
 */
struct RxCamSpace3DVertex
{
    /* Position in sheared camera-space (pre-projection) */
    RwV3d           cameraVertex; /**< \ref RwV3d camera-space position of the vertex */
    /* Clip flags on this vertex */
    RwUInt8         clipFlags;    /**< Clip flags for the vertex generated during transformation into camera-space, see \ref RwClipFlag */
    RwUInt8         pad[3];       /**< Alignment padding */
    /* Lit colour */
    RwRGBAReal      col;          /**< Accumulated \ref RwReal light values (initialized to zero or prelight colours) */
    /* Only used by the clipper */
    RwReal          u;            /**< Texture U coordinate */
    RwReal          v;            /**< Texture V coordinate */
};

/* Supports pipeline1 apps: */
/**
 * \ingroup datatypes
 * \typedef RwCameraVertex
 * typedef for a structure describing a camera-space 3D vertex.
 */
typedef RxCamSpace3DVertex RwCameraVertex;

/* (used during lighting) Doesn't use alpha yet, but it will */
#define RxCamSpace3DVertexSetRGBA(camvert, r, g, b, a)  \
MACRO_START                                             \
{                                                       \
    ((camvert)->col.red = (r));                         \
    ((camvert)->col.green = (g));                       \
    ((camvert)->col.blue = (b));                        \
    ((camvert)->col.alpha = (a));                       \
}                                                       \
MACRO_STOP

#define RxCamSpace3DVertexAddRGBA(camvert, r, g, b, a)  \
MACRO_START                                             \
{                                                       \
    ((camvert)->col.red += (r));                        \
    ((camvert)->col.green += (g));                      \
    ((camvert)->col.blue += (b));                       \
    ((camvert)->col.alpha += (a));                      \
}                                                       \
MACRO_STOP

/* LEGACY-SUPPORT macros */
#define RXCAMSPACE3DVERTEXSetRGBA(camvert, r, g, b, a)  \
    RxCamSpace3DVertexSetRGBA(camvert, r, g, b, a)
#define RXCAMSPACE3DVERTEXAddRGBA(camvert, r, g, b, a)  \
    RxCamSpace3DVertexAddRGBA(camvert, r, g, b, a)

/* MeshState.csl */


/**
 * \ingroup rwcoregeneric
 * \ref RxGeometryFlag
 * Flags describing geometry properties
 */
enum RxGeometryFlag
{
    rxGEOMETRY_TRISTRIP      = 0x01,  /**<This geometry's meshes can be rendered as tristrips */
    rxGEOMETRY_POSITIONS     = 0x02,  /**<This geometry has positions */
    rxGEOMETRY_TEXTURED      = 0x04,  /**<This geometry has textures applied */
    rxGEOMETRY_PRELIT        = 0x08,  /**<This geometry has luminance values */
    rxGEOMETRY_NORMALS       = 0x10,  /**<This geometry has normals */
    rxGEOMETRY_LIGHT         = 0x20,  /**<This geometry will be lit */
    rxGEOMETRY_MODULATE      = 0x40,  /**<This geometry will modulate the material color with the vertex colors (pre-lit + lit) */
    rxGEOMETRY_TEXTURED2     = 0x80,  /**<This geometry has 2 set of texture coordinates */

    rxGEOMETRY_COLORED       = 0x100, /**<This mesh specifies per-vertex colors. NB: ONLY USED IN IM3D */

    rxGEOMETRYFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
/**
 * \ingroup rwcoregeneric
 * \typedef RxGeometryFlag
 * Typedef for RxGeometryFlag enumeration describing geometry properties
 */
typedef enum RxGeometryFlag RxGeometryFlag;

typedef struct RxMeshStateVector RxMeshStateVector;

/**
 * \ingroup rwcoregeneric
 * \struct RxMeshStateVector
 * Structure describing a mesh-state vector,
 * used by the RxClMeshState cluster
 */
struct RxMeshStateVector
{
    RwInt32             Flags;              /**< \ref RxGeometryFlag Flags from the source geometry */
    void               *SourceObject;       /**< A void pointer. In immediate mode it points to an
                                             * internal structure and in atomic/world-sector instance
                                             * or material render pipelines it points to an \ref RpMaterial. */
    RwMatrix            Obj2World;          /**< \ref RwMatrix to transform from object-space to world-space */
    RwMatrix            Obj2Cam;            /**< \ref RwMatrix to transform from object-space to camera-space */
    RwSurfaceProperties SurfaceProperties;  /**< \ref RwSurfaceProperties */
    /* We can't necessarily reference a RpMaterial in here (i.e with Im3D) */
    RwTexture          *Texture;            /**< A pointer to a \ref RwTexture */
    RwRGBA              MatCol;             /**< \ref RwRGBA material colour */
    /* Material render pipeline, if appropriate */
    RxPipeline        *Pipeline;            /**< A pointer to the material render pipeline where appropriate */
    /* rwPRIMTYPETRILIST/TRIFAN/TRISTRIP/LINELIST/POLYLINE */
    RwPrimitiveType     PrimType;           /**< \ref RwPrimitiveType primitive type */
    /* Interpretation based on PrimType */
    RwUInt32            NumElements;        /**< \ref RwUInt32 number of elements (triangles, lines...) */
    RwUInt32            NumVertices;        /**< \ref RwUInt32 number of vertices */
    RwInt32             ClipFlagsOr;        /**< Boolean OR of the \ref RwClipFlag clip flags of all vertices in the mesh */
    RwInt32             ClipFlagsAnd;       /**< Boolean AND of the \ref RwClipFlag clip flags of all vertices in the mesh */
    void               *SourceMesh;         /**< A void pointer to the source \ref RpMesh */
    void               *DataObject;         /**< Mirrors the void data pointer of \ref RxPipelineExecute */
};

/* RxScatter.csl */
typedef struct RxScatter RxScatter;
/**
 * \ingroup rwcoregeneric
 * \struct RxScatter
 * Structure used by the RxClScatter cluster
 */
struct RxScatter
{
    RxPipeline    *pipeline; /**< \ref RxPipeline pointer, causes Scatter.csl
                              * to spit the packet out to the specified pipeline */
    RxPipelineNode *node;    /**< \ref RxPipelineNode pointer, causes Scatter.csl
                              * to send the packet to the specified PipelineNode
                              * (as long as it is actually one of its outputs!) */
};

/* RxInterpolants.csl */
typedef struct RxInterp RxInterp;
/**
 * \ingroup rwcoregeneric
 * \struct RxInterp
 * Structure used by the RxClInterp cluster
 */
struct RxInterp
{
    RxVertexIndex originalVert; /**< \ref RxVertexIndex index to the new vertex generated on the clipped edge */
    RxVertexIndex parentVert1;  /**< \ref RxVertexIndex index to the first vertex of the clipped edge */
    RxVertexIndex parentVert2;  /**< \ref RxVertexIndex index to the second vertex of the clipped edge */
    RwReal        interp;       /**< \ref RwReal interpolant along the clipped edge */
};

/* RxUVs.csl */
typedef struct RxUV RxUV;
/**
 * \ingroup rwcoregeneric
 * \struct RxUV
 * Structure used by the RxClUV cluster
 */
struct RxUV
{
    RwReal u; /**< \ref RwReal U texture coordinate */
    RwReal v; /**< \ref RwReal V texture coordinate */
};

/* RxTriPlanes.csl */
typedef struct RxTriPlane RxTriPlane;
/**
 * \ingroup rwcoregeneric
 * \struct RxTriPlane
 * for the packed plane structure
 * used in RpWorlds and by the RxClTriPlane cluster
 */
struct RxTriPlane
{
    /* Packed plane format used in RpWorlds */
    RwUInt32 N; /**< \ref RwUInt32 Packed normal */
    RwReal   w; /**< \ref RwReal distance from origin */
};

/* RxVSteps.csl */

#if (defined(_MSC_VER))
#  if (_MSC_VER>=1000)
#    pragma pack(push, 1)
#  endif /* (_MSC_VER>=1000) */
#endif /* (defined(_MSC_VER)) */

typedef struct RxVStep RxVStep;
/**
 * \ingroup rwcoregeneric
 * \struct RxVStep
 * Structure used by the RxClVStep cluster
 */
struct RxVStep
{
    RwUInt8 step; /**< \ref RwUInt8 The number of vertices after the current one
                   * which can be skipped in lighting and other calculations because,
                   * for example, they belong only to back-facing triangles */
};

#if (defined(_MSC_VER))
#  if (_MSC_VER>=1000)
#    pragma pack(pop)
#  endif /* (_MSC_VER>=1000) */
#endif /* (defined(_MSC_VER)) */

/* CamNorms.csl */
/**
 * \ingroup rwcoregeneric
 * \typedef RxCamNorm
 * typedef for \ref RwV3d used by the RxClVStep cluster */
typedef RwV3d RxCamNorm;


#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Uses the RxObjSpace3DVertex type (see pipmodel.h) */
extern RxClusterDefinition RxClObjSpace3DVertices;
/* Uses the RxCamSpace3DVertex type */
extern RxClusterDefinition RxClCamSpace3DVertices;
/* Uses the RxScrSpace2DVertex type (see pipmodel.h) */
extern RxClusterDefinition RxClScrSpace2DVertices;
/* Uses the RxInterp type */
extern RxClusterDefinition RxClInterpolants;
/* Uses the RxMeshStateVector type */
extern RxClusterDefinition RxClMeshState;
/* Uses the RxRenderStateVector type (p2renderstate.c/h) */
extern RxClusterDefinition RxClRenderState;
/* Uses the RxVertexIndex type */
extern RxClusterDefinition RxClIndices;
/* Uses the RxScatter type */
extern RxClusterDefinition RxClScatter;
/* Uses the RxTriPlane type */
extern RxClusterDefinition RxClTriPlanes;
/* Uses the RxUV type */
extern RxClusterDefinition RxClUVs;
/* Uses the RxVStep type */
extern RxClusterDefinition RxClVSteps;
/* Uses the RwRGBAReal type */
extern RxClusterDefinition RxClRGBAs;
/* Uses the RxCamNorm type */
extern RxClusterDefinition RxClCamNorms;

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/baim3d.h ---*/

/**
 * \ingroup datatypes
 * RwIm3DTransformFlags 
 *  The bit-field type  RwIm3DTransformFlags
 * specifies options available for controlling execution of the 3D immediate
 * mode pipeline (see API function \ref RwIm3DTransform):*/
enum RwIm3DTransformFlags
{
    rwIM3D_VERTEXUV      = 1,   /**<Texture coordinates in source vertices should be used */
    rwIM3D_ALLOPAQUE     = 2,   /**<All source vertices are opaque (alpha is 255) */
    rwIM3D_NOCLIP        = 4,   /**<No clipping should be performed on the geometry (the
                                 * app may know it is all onscreen or within the guard band clipping
                                 * region for the current hardware, so clipping can be skipped) */
    rwIM3D_VERTEXXYZ     = 8,   /**<World coordinates */
    rwIM3D_VERTEXRGBA    = 16,  /**<Vertex color */

    rwIM3DTRANSFORMFLAGSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwIm3DTransformFlags RwIm3DTransformFlags;



typedef struct rwIm3DPool            rwIm3DPool;
typedef struct rwImmediGlobals       rwImmediGlobals;
typedef struct rwIm3DRenderPipelines rwIm3DRenderPipelines;
typedef struct _rwIm3DPoolStash       _rwIm3DPoolStash;

#if (0 && defined(SKY2))
typedef struct rwIm3DVertexCache     RwIm3DVertexCache;
#endif /* (0&& defined(SKY2)) */

/* complete information to reconstruct post-transform Im3D "mesh" packet */
struct _rwIm3DPoolStash
{
    RwUInt32                 flags;    /* rwIM3D_VERTEXUV, rwIM3D_ALLOPAQUE, rwIM3D_NOCLIP etc */
    RwMatrix                *ltm;      /* world-space frame of the vertices, if they have one */
    RwUInt32                 numVerts;
    RxObjSpace3DVertex      *objVerts;
    RxCamSpace3DVertex      *camVerts;
    RxScrSpace2DVertex      *devVerts;
    RxMeshStateVector       *meshState;
    RxRenderStateVector     *renderState;
    RxPipeline              *pipeline;
    RwPrimitiveType          primType;
    RxVertexIndex           *indices;
    RwUInt32                 numIndices;
};

/* Used as a cache of transformed vertices */
struct rwIm3DPool
{
    RwUInt16         numElements; /* could become RwUInt32 nowadays */
    RwUInt16         pad;         /* alignment padding */
    void            *elements;    /* the original array of verts (or whatever...) - referenced not copied */
    RwInt32          stride;      /* the stride of the element */
    _rwIm3DPoolStash  stash;
};

struct rwIm3DRenderPipelines
{
    /* One Im3D render pipeline pointer per rwPRIMTYPE
     * (several pointers may point to the same pipeline though) */
    RxPipeline *triList;
    RxPipeline *triFan;
    RxPipeline *triStrip;
    RxPipeline *lineList;
    RxPipeline *polyLine;
    RxPipeline *pointList;
};

struct rwImmediGlobals
{
    RxPipeline           *genericIm3DTransformPipeline;
    rwIm3DRenderPipelines genericIm3DRenderPipelines;

    RxPipeline           *im3DTransformPipeline;
    rwIm3DRenderPipelines im3DRenderPipelines;

    /* Platforms that have their own non-generic pipelines
     * (OPENGL, D3D7, SKY2, KAMUI2, DOLPHIN) put them here: */
    RxPipeline           *platformIm3DTransformPipeline;
    rwIm3DRenderPipelines platformIm3DRenderPipelines;

#if (defined(SKY2_DRVMODEL_H))
    /* PS2All/PS2AllMat pipelines */
    RxPipeline           *ps2AllIm3DRenderPipeline;
    /* The PS2All pipe automatically calls this PS2AllMat pipe */
    RxPipeline           *ps2AllMatIm3DPipeline;
#endif /* (defined(SKY2_DRVMODEL_H)) */

    rwIm3DPool   curPool;              /* The current cache of transformed vertices */
};


#ifdef    __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern rwIm3DPool *_rwIm3DGetPool( void );

extern void  *RwIm3DTransform(RwIm3DVertex *pVerts, RwUInt32 numVerts,
                              RwMatrix *ltm, RwUInt32 flags);
extern RwBool RwIm3DEnd(void);

extern RwBool RwIm3DRenderLine(RwInt32 vert1, RwInt32 vert2);
extern RwBool RwIm3DRenderTriangle(RwInt32 vert1, RwInt32 vert2,
                                   RwInt32 vert3);
extern RwBool RwIm3DRenderIndexedPrimitive(RwPrimitiveType primType,
                                           RwImVertexIndex *indices,
                                           RwInt32 numIndices);
extern RwBool RwIm3DRenderPrimitive(RwPrimitiveType primType);

/* NOT COMPATIBLE WITH POWERPIPE: extern RwRenderPipeline *RwIm3DGetRenderPipeline(void); */

extern RxPipeline *RwIm3DGetGenericTransformPipeline(void);
extern RxPipeline *RwIm3DGetGenericRenderPipeline(RwPrimitiveType primType);

extern RxPipeline *RwIm3DGetTransformPipeline(void);
extern RxPipeline *RwIm3DGetRenderPipeline(   RwPrimitiveType  primType);
extern RxPipeline *RwIm3DSetTransformPipeline(RxPipeline *pipeline);
extern RxPipeline *RwIm3DSetRenderPipeline(   RxPipeline *pipeline,
                                              RwPrimitiveType primType);

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/sky2/im3dpipe.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/baresamp.h ---*/

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

extern RwImage *RwImageResample(RwImage *dstImage, const RwImage *srcImage);
extern RwImage *RwImageCreateResample(const RwImage *srcImage, RwInt32 width,
                                                               RwInt32 height);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/baimras.h ---*/
/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Images from rasters */
extern RwImage *RwImageSetFromRaster(RwImage *image, RwRaster *raster);

/* Rasters from images */
extern RwRaster *RwRasterSetFromImage(RwRaster *raster, RwImage *image);

/* Finding raster formats */
extern RwRGBA *RwRGBAGetRasterPixel(RwRGBA *rgbOut, RwRaster *raster,
                                   RwInt32 x, RwInt32 y);

/* Read a raster */
extern RwRaster *RwRasterRead(const RwChar *filename);
extern RwRaster *RwRasterReadMaskedRaster(const RwChar *filename, const RwChar *maskname);

/* Finding appropriate raster formats */
extern RwImage *RwImageFindRasterFormat(RwImage *ipImage,RwInt32 nRasterType,
                                        RwInt32 *npWidth,RwInt32 *npHeight,
                                        RwInt32 *npDepth,RwInt32 *npFormat);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/baimform.h ---*/

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

extern RwImage     *RwImageReadBMP(const RwChar * imageName);
extern RwImage     *RwImageReadRAS(const RwChar * imageName);
extern RwImage     *RwImageWriteRAS(RwImage * image,
                                    const RwChar * imageName);
extern RwImage     *RwImageWriteBMP(RwImage * image,
                                    const RwChar * imageName);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/badevice.h ---*/
/***************************************************************************/
/************************* System Requests *********************************/
/***************************************************************************/

/* Device controls:
 *
 * rwDEVICESYSTEMOPEN(NULL, RwEngineOpenParams *openParams, 0)
 * rwDEVICESYSTEMCLOSE(NULL, NULL, 0)
 * rwDEVICESYSTEMSTART(NULL, NULL, 0)
 * rwDEVICESYSTEMSTOP(NULL, NULL, 0)
 * rwDEVICESYSTEMREGISTER(RwDevice *coreDeviceBlock, RwMemoryFunctions *memFuncs, 0)
 * rwDEVICESYSTEMGETNUMMODES(RwInt32 *numModes, NULL, 0)
 * rwDEVICESYSTEMGETMODEINFO(RwVideoMode *modeinfo, NULL, RwInt32 modeNum)
 * rwDEVICESYSTEMUSEMODE(NULL, NULL, RwInt32 modeNum)
 * rwDEVICESYSTEMFOCUS(NULL, NULL, RwBool gainFocus)
 * rwDEVICESYSTEMINITPIPELINE(NULL, RwRenderPipeline *pipeline, 0)
 * rwDEVICESYSTEMGETMODE(RwInt32 *curMode, NULL, 0)
 * rwDEVICESYSTEMSTANDARDS(RwStandardFunc *fnPtrArray, NULL, RwInt32 arraySize)
 * rwDEVICESYSTEMGETTEXMEMSIZE(RwInt32 *texMemSizeOut, NULL, 0)
 * rwDEVICESYSTEMGETNUMSUBSYSTEMS(RwInt32 *numSubSystemsOut, NULL, 0)
 * rwDEVICESYSTEMGETSUBSYSTEMINFO(RwSubSystemInfo *subSystemInfo, NULL, RwInt32 subSystemNum)
 * rwDEVICESYSTEMGETCURRENTSUBSYSTEM(RwInt32 *curSubSystem, NULL, 0)
 * rwDEVICESYSTEMSETSUBSYSTEM(NULL, NULL, RwInt32 subSystemNum)
 * rwDEVICESYSTEMFINALIZESTART(NULL, NULL, 0)
 * rwDEVICESYSTEMINITIATESTOP(NULL, NULL, 0)
 * rwDEVICESYSTEMRXPIPELINEREQUESTPIPE(RxPipeline **pipelineRef, NULL, RwInt32 pipeType)
 * rwDEVICESYSTEMDD         - start of device specific controls
 */

#define rwPIPETYPEMATERIAL            0
#define rwPIPETYPEWORLDSECTORINSTANCE 1
#define rwPIPETYPEATOMICINSTANCE      2

enum RwCoreDeviceSystemFn
{
    rwDEVICESYSTEMOPEN                  = 0x00,
    rwDEVICESYSTEMCLOSE,
    rwDEVICESYSTEMSTART,
    rwDEVICESYSTEMSTOP,
    rwDEVICESYSTEMREGISTER,
    rwDEVICESYSTEMGETNUMMODES,
    rwDEVICESYSTEMGETMODEINFO,
    rwDEVICESYSTEMUSEMODE,
    rwDEVICESYSTEMFOCUS,
    rwDEVICESYSTEMINITPIPELINE,
    rwDEVICESYSTEMGETMODE,
    rwDEVICESYSTEMSTANDARDS,
    rwDEVICESYSTEMGETTEXMEMSIZE,
    rwDEVICESYSTEMGETNUMSUBSYSTEMS,
    rwDEVICESYSTEMGETSUBSYSTEMINFO,
    rwDEVICESYSTEMGETCURRENTSUBSYSTEM,
    rwDEVICESYSTEMSETSUBSYSTEM,
    rwDEVICESYSTEMFINALIZESTART,
    rwDEVICESYSTEMINITIATESTOP,
    rwDEVICESYSTEMGETMAXTEXTURESIZE,
    rwDEVICESYSTEMRXPIPELINEREQUESTPIPE,
    rwDEVICESYSTEMGETMETRICBLOCK,
    rwDEVICESYSTEMDD                    = 0x1000,
    rwCOREDEVICESYSTEMFNFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwCoreDeviceSystemFn RwCoreDeviceSystemFn;

/******************************************************************************/
/********************* Standard functions *************************************/
/******************************************************************************/

#define rwSTANDARDNASTANDARD            0
#define rwSTANDARDCAMERABEGINUPDATE     1   /* Start 3d camera update */
#define rwSTANDARDRGBTOPIXEL            2   /* For an RGB value return a pixel value */
#define rwSTANDARDPIXELTORGB            3   /* For a pixel value returns a RGB value */
#define rwSTANDARDRASTERCREATE          4   /* Create an raster */
#define rwSTANDARDRASTERDESTROY         5   /* Raster destroy */
#define rwSTANDARDIMAGEGETRASTER        6   /* Get image from a raster */
#define rwSTANDARDRASTERSETIMAGE        7   /* Set raster from an image */
#define rwSTANDARDTEXTURESETRASTER      8   /* Set texture's raster */
#define rwSTANDARDIMAGEFINDRASTERFORMAT 9   /* Find a suitable raster format for an image */
#define rwSTANDARDCAMERAENDUPDATE       10  /* End 3d camera update */
#define rwSTANDARDSETRASTERCONTEXT      11  /* Start destination of 2d operations */
#define rwSTANDARDRASTERSUBRASTER       12  /* Make a raster inside another raster */
#define rwSTANDARDRASTERCLEARRECT       13  /* Clear a rectangle of the current dest raster */
#define rwSTANDARDRASTERCLEAR           14  /* Clear the current dest raster */
#define rwSTANDARDRASTERLOCK            15  /* Lock a raster to get it's pixels */
#define rwSTANDARDRASTERUNLOCK          16  /* Unlock a raster to return it's pixels */
#define rwSTANDARDRASTERRENDER          17  /* Render a raster (not scaled, but masked) */
#define rwSTANDARDRASTERRENDERSCALED    18  /* Render a raster (scaled and masked) */
#define rwSTANDARDRASTERRENDERFAST      19  /* Render a raster (not scaled or masked) */
#define rwSTANDARDRASTERSHOWRASTER      20  /* Show a camera raster */
#define rwSTANDARDCAMERACLEAR           21  /* Clear a camera's raster and/or Z raster */
#define rwSTANDARDHINTRENDERF2B         22  /* Set hint for rendering direction in the world */
#define rwSTANDARDRASTERLOCKPALETTE     23  /* Lock a raster to get it's palette */
#define rwSTANDARDRASTERUNLOCKPALETTE   24  /* Unlock a raster to return it's palette */
#define rwSTANDARDNATIVETEXTUREGETSIZE  25  /* Get size of native texture when written to a stream */
#define rwSTANDARDNATIVETEXTUREREAD     26  /* Read native texture from the stream */
#define rwSTANDARDNATIVETEXTUREWRITE    27  /* Write native texture to the stream */
#define rwSTANDARDRASTERGETMIPLEVELS    28  /* Get the number of mip levels in a raster */
#define rwSTANDARDNUMOFSTANDARD         29

/****************************************************************************
 Global Types
 */

/* Standard functions */
typedef RwBool (*RwStandardFunc)(void *pOut,void *pInOut,RwInt32 nI);

typedef struct RwEngineOpenParams RwEngineOpenParams;

/**
 * \ingroup datatypes
 * \struct RwEngineOpenParams
 * This type is used to specify device dependent parameters 
 * for use by the API function \ref RwEngineOpen.  
 * For a Windows application the displayID field 
 * should be set to the window's handle (of type HWND).  
 * For NULL and sky libraries displayID=0:
 */
struct RwEngineOpenParams
{
    void    *displayID;     /**< Display Identifier */
};

/* nOption is one of a list of possible System defines (see above) */
typedef RwBool
    (*RwSystemFunc)(RwInt32 nOption,
                    void *pOut,
                    void *pInOut,
                    RwInt32 nIn);

/* Device block */
typedef RwBool
    (*RwRenderStateSetFunction)(RwRenderState nState,void *pParam);

typedef RwBool
    (*RwRenderStateGetFunction)(RwRenderState nState,void *pParam);

typedef RwBool
    (*RwIm2DRenderLineFunction)(RwIm2DVertex *vertices,
                                RwInt32 numVertices,
                                RwInt32 vert1,
                                RwInt32 vert2);

typedef RwBool
    (*RwIm2DRenderTriangleFunction)(RwIm2DVertex *vertices,
                                    RwInt32 numVertices,
                                    RwInt32 vert1,
                                    RwInt32 vert2,
                                    RwInt32 vert3);

typedef RwBool
    (*RwIm2DRenderPrimitiveFunction)(RwPrimitiveType primType,
                                     RwIm2DVertex *vertices,
                                     RwInt32 numVertices);

typedef RwBool
    (*RwIm2DRenderIndexedPrimitiveFunction)(RwPrimitiveType primType,
                                            RwIm2DVertex *vertices,
                                            RwInt32 numVertices,
                                            RwImVertexIndex *indices,
                                            RwInt32 numIndices);

typedef RwBool
    (*RwIm3DRenderLineFunction)(RwInt32 vert1,
                                RwInt32 vert2);

typedef RwBool
    (*RwIm3DRenderTriangleFunction)(RwInt32 vert1,
                                    RwInt32 vert2,
                                    RwInt32 vert3);

typedef RwBool
    (*RwIm3DRenderPrimitiveFunction)(RwPrimitiveType primType);

typedef RwBool
    (*RwIm3DRenderIndexedPrimitiveFunction)(RwPrimitiveType primtype,
                                            RwImVertexIndex *indices,
                                            RwInt32 numIndices);


typedef struct RwDevice RwDevice;
/**
 * \ingroup datatypes
 * \struct RwDevice
 * Structure describing a display device
 */
struct RwDevice
{
    RwReal                                  gammaCorrection; /**<Gamma correction  */
    RwSystemFunc                            fpSystem;  /**< System handler */
    RwReal                                  zBufferNear; /**< Near Z buffer value */
    RwReal                                  zBufferFar; /**< Far Z buffer value */

    /* Immediate mode functions */
    RwRenderStateSetFunction                fpRenderStateSet; /**< Internal Use */
    RwRenderStateGetFunction                fpRenderStateGet; /**< Internal Use */

    /* Render functions */
    RwIm2DRenderLineFunction                fpIm2DRenderLine; /**< Internal Use */
    RwIm2DRenderTriangleFunction            fpIm2DRenderTriangle; /**< Internal Use */
    RwIm2DRenderPrimitiveFunction           fpIm2DRenderPrimitive; /**< Internal Use */
    RwIm2DRenderIndexedPrimitiveFunction    fpIm2DRenderIndexedPrimitive; /**< Internal Use */

    RwIm3DRenderLineFunction                fpIm3DRenderLine; /**< Internal Use */
    RwIm3DRenderTriangleFunction            fpIm3DRenderTriangle; /**< Internal Use */
    RwIm3DRenderPrimitiveFunction           fpIm3DRenderPrimitive; /**< Internal Use */
    RwIm3DRenderIndexedPrimitiveFunction    fpIm3DRenderIndexedPrimitive; /**< Internal Use */
};

typedef struct RwMetrics RwMetrics;
/**
 * \ingroup datatypes
 * \struct RwMetrics
 * This structure provides information about the performance
 * of the application.  The metrics are recorded only in the metrics
 * libraries.  To use metrics you should compile with the RWMETRICS
 * preprocessor symbol defines, and link with the metrics libraries
 * that ship with the SDK.  The metrics are recorded on a per-frame
 * basis.  Each platform may provide additional information that
 * is specific to that platform.  Note that either the
 * \ref numTextureUploads or \ref numResourceAllocs being non-zero can
 * be considered as bad news and will indicate a significantly
 * reduced rendering performance.
 */
struct RwMetrics
{
    RwUInt32    numTriangles;           /**< Number of triangles processed */
    RwUInt32    numProcTriangles;       /**< Number of mesh triangles processed */
    RwUInt32    numVertices;            /**< Number of vertices processed */
    RwUInt32    numTextureUploads;      /**< Number of textures swapped */
    RwUInt32    sizeTextureUploads;     /**< Size of textures swapped */
    RwUInt32    numResourceAllocs;      /**< Number of resource blocks swapped */
    void        *devSpecificMetrics;    /**< Device specific metrics */
};

#define SUBSYSTEMNAME_MAXLEN 80

typedef struct RwSubSystemInfo RwSubSystemInfo;
/**
 * \ingroup datatypes
 * \struct RwSubSystemInfo
 * This type is used to represent information about a device.  
 * The only available field specifies a character string 
 * which identifies the subsystem
 * (see API function \ref RwEngineGetSubSystemInfo). */
struct RwSubSystemInfo
{
    RwChar  name[SUBSYSTEMNAME_MAXLEN]; /**< Sub system string */
};


/* Video modes */
/* These are flag bits which may be ORd */

/**
 * \ingroup datatypes
 * RwVideoModeFlag 
 * These flags specify the type of display that RenderWare
 * will use.  The flags may be ORed together to build composite modes.
 * Note that not all modes are supported on all platforms.
 */
enum RwVideoModeFlag
{
    rwVIDEOMODEEXCLUSIVE  = 0x1,    /**<Exclusive (i.e. full-screen) */
    rwVIDEOMODEINTERLACE  = 0x2,    /**<Interlaced */
    rwVIDEOMODEFFINTERLACE  = 0x4,  /**<Flicker Free Interlaced */
    rwVIDEOMODEFSAA0 = 0x8,         /**<Full-screen antialiasing mode 0 */
    rwVIDEOMODEFSAA1 = 0x10,        /**<Full-screen antialiasing mode 1 */
    rwVIDEOMODEforceEnumSize  = 0x7fffffff,
    rwVIDEOMODEFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwVideoModeFlag RwVideoModeFlag;

typedef struct RwVideoMode RwVideoMode;
/**
 * \ingroup datatypes
 * \struct RwVideoMode
 * This type represents a video mode available on a device specified
 * by the frame buffer resolution (width and height) and depth, 
 * and a flag indicating  whether the device has exclusive use of 
 * the mode (see API function \ref RwEngineGetVideoModeInfo): */
struct RwVideoMode
{
        RwInt32         width;  /**< Width */
        RwInt32         height; /**< Height */
        RwInt32         depth;  /**< Depth */
        RwVideoModeFlag flags;  /**< Flags */
};

/**
 * \ingroup datatypes
 * RwEngineInitFlag 
 * Engine initialization flags.  An application can use
 * these to control the memory manager that RenderWare uses for dynamic
 * memory management.  By default RenderWare uses FreeLists.  This is the
 * preferred way of using RenderWare.  If the application does not want
 * RenderWare to use the memory manager, then the application can pass
 * rwENGINEINITNOFREELISTS as the argument to \ref RwEngineInit and
 * RenderWare will replace freelist calls to corresponding calls to
 * RwMalloc and RwFree.  This will result in more memory management
 * related calls.
 */
enum RwEngineInitFlag
{
    rwENGINEINITFREELISTS = 0,      /**<Use Freelists */
    rwENGINEINITNOFREELISTS = 0x1,  /**<Don't use Freelists */
    rwENGINEINITFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwEngineInitFlag RwEngineInitFlag;

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Get the library binary version */
extern RwInt32 RwEngineGetVersion(void);

/* Sequence of events to get RenderWare up and running */
extern RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags);
extern RwInt32 RwEngineRegisterPlugin(RwInt32 size, RwUInt32 pluginID,
                                  RwPluginObjectConstructor initCB,
                                  RwPluginObjectDestructor termCB);
extern RwInt32 RwEngineGetPluginOffset(RwUInt32 pluginID);
extern RwBool RwEngineOpen(RwEngineOpenParams *initParams);
extern RwBool RwEngineStart(void);
extern RwBool RwEngineStop(void);
extern RwBool RwEngineClose(void);
extern RwBool RwEngineTerm(void);

/* Finding out about the rendering sub systems available */
extern RwInt32 RwEngineGetNumSubSystems(void);
extern RwSubSystemInfo *RwEngineGetSubSystemInfo(RwSubSystemInfo *subSystemInfo, RwInt32 subSystemIndex);
extern RwInt32 RwEngineGetCurrentSubSystem(void);
extern RwBool RwEngineSetSubSystem(RwInt32 subSystemIndex);

/* Finding out about the modes available */
extern RwInt32 RwEngineGetNumVideoModes(void);
extern RwVideoMode *RwEngineGetVideoModeInfo(RwVideoMode *modeinfo, RwInt32 modeIndex);
extern RwInt32 RwEngineGetCurrentVideoMode(void);
extern RwBool RwEngineSetVideoMode(RwInt32 modeIndex);

/* Finding out how much texture memory is available */
extern RwInt32 RwEngineGetTextureMemorySize(void);
extern RwInt32 RwEngineGetMaxTextureSize(void);

/* Getting/Releasing the focus */
extern RwBool RwEngineSetFocus(RwBool enable);

/* Getting metrics */
extern RwMetrics *RwEngineGetMetrics(void);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/balibtyp.h ---*/
/* Finding MSBs */

#define RWBYTEFINDMSB(a) \
   (_rwMsbBit[(a)]-1)

#define RWWORDFINDMSB(a) \
   (((a)&0xff00)?RWBYTEFINDMSB((a)>>8)+8: RWBYTEFINDMSB(a))

#define RWLONGFINDMSB(a) \
   (((a)&0xffff0000UL)?RWWORDFINDMSB((a)>>16)+16: RWWORDFINDMSB(a))

/****************************************************************************
 Defines
 */

/* macro used to access plugin data in objects */
#define RWPLUGINOFFSET(type, base, offset) \
   ((type *)((RwUInt8 *)base + offset))
#define RWPLUGINOFFSETCONST(type, base, offset) \
   ((const type *)((const RwUInt8 *)base + offset))

/* macro used to access global data structure (the root type is RwGlobals) */
#define RWSRCGLOBAL(variable) \
   (((RwGlobals *)RwEngineInstance)->variable)

#define RWASSERTISTYPE(_f, _t) \
   RWASSERT((((const RwObject *)(_f))->type)==(_t))

/****************************************************************************
 Global Types
 */

enum RwEngineStatus
{
    rwENGINESTATUSIDLE = 0,                     /* This needs to be zero */
    rwENGINESTATUSINITED = 1,
    rwENGINESTATUSOPENED = 2,
    rwENGINESTATUSSTARTED = 3,
    rwENGINESTATUSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwEngineStatus RwEngineStatus;

typedef struct RwGlobals RwGlobals;
struct RwGlobals
{
#ifdef RWDEBUG
        RwDebugHandler      debugFunction;          /* debug string handler */
        void                *debugFile;             /* debug output file */
        RwInt32             debugStackDepth;        /* current depth of function stack */
        RwBool              debugTrace;             /* is function tracing enabled */
#endif

        /* Current entities */
        void                *curCamera;             /* Current camera */
        void                *curWorld;              /* Current World */

        /* Checking counters */
        RwUInt16            renderFrame;            /* Camera display count */
        RwUInt16            collisionFrame;
        RwUInt16            lightFrame;
        RwUInt16            pad;                    /* Longword align it again */

        /* For the currently accessed device */
        RwDevice            dOpenDevice;

        /* Standard renderers and functions */
        RwStandardFunc      stdFunc[rwSTANDARDNUMOFSTANDARD];

        /* All of the frames which have been updated */
        RwLinkList          dirtyFrameList;

        /* The file functions */
        RwFileFunctions     fileFuncs;

        /* The string functions */
        RwStringFunctions   stringFuncs;

        /* The memory allocation functions */
        RwMemoryFunctions   memoryFuncs;
#ifdef RWDEBUG
        RwBool              freeListExtraDebug;
#endif /* RWDEBUG */

        /* virtual memory alloc/free functions */
        RwMemoryAllocFn         memoryAlloc;
        RwMemoryFreeFn          memoryFree;

        RwMetrics           *metrics;

        /* Current engine status */
        RwEngineStatus      engineStatus;
};

typedef struct RwModuleInfo RwModuleInfo;
struct RwModuleInfo
{
        RwInt32     globalsOffset;
        RwInt32     numInstances;
};



/****************************************************************************
 Program wide globals
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

#ifdef RWGLOBALSIZE
extern RwUInt32     ourGlobals[RWGLOBALSIZE / sizeof(RwUInt32)];
#define RwEngineInstance ourGlobals
#else /* RWGLOBALSIZE */
extern void         *RwEngineInstance;
#endif /* RWGLOBALSIZE */

extern RwInt8 _rwMsbBit[];

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/babintex.h ---*/
/****************************************************************************
 Global types
 */

typedef struct rpTextureChunkInfo RwTextureChunkInfo;
struct rpTextureChunkInfo
{
    RwTextureFilterMode filtering;
    RwTextureAddressMode addressing;
};

/* Bit flags defining properties of textures when stream */
enum RwTextureStreamFlags
{
    rwNATEXTURESTREAMFLAG = 0x00,
    rwTEXTURESTREAMFLAGSUSERMIPMAPS = 0x01,
    rwTEXTURESTREAMFLAGSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwTextureStreamFlags RwTextureStreamFlags;
/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Texture binary format */
extern RwInt32 RwTextureRegisterPluginStream(RwUInt32 pluginID,
                                             RwPluginDataChunkReadCallBack readCB,
                                             RwPluginDataChunkWriteCallBack writeCB,
                                             RwPluginDataChunkGetSizeCallBack getSizeCB);
extern RwInt32 RwTextureSetStreamAlwaysCallBack(
                   RwUInt32 pluginID,
                   RwPluginDataChunkAlwaysCallBack alwaysCB);
extern RwUInt32 RwTextureStreamGetSize(const RwTexture *texture);
extern RwTexture *RwTextureStreamRead(RwStream *stream);
extern const RwTexture *RwTextureStreamWrite(const RwTexture *texture, RwStream *stream);
extern RwTextureChunkInfo *
RwTextureChunkInfoRead(RwStream *stream, RwTextureChunkInfo *textureChunkInfo, RwInt32 *bytesRead);

/* Texture dictionary binary format */
extern RwInt32 RwTexDictionaryRegisterPluginStream(RwUInt32 pluginID,
                                                   RwPluginDataChunkReadCallBack readCB,
                                                   RwPluginDataChunkWriteCallBack writeCB,
                                                   RwPluginDataChunkGetSizeCallBack getSizeCB);
extern RwInt32 RwTexDictionarySetStreamAlwaysCallBack(
                   RwUInt32 pluginID,
                   RwPluginDataChunkAlwaysCallBack alwaysCB);
extern RwUInt32 RwTexDictionaryStreamGetSize(const RwTexDictionary *texDict);
extern RwTexDictionary *RwTexDictionaryStreamRead(RwStream *stream);
extern const RwTexDictionary *RwTexDictionaryStreamWrite(const RwTexDictionary *texDict, RwStream *stream);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/babinmtx.h ---*/

/****************************************************************************
 Global types
 */

/* Matrix stream format */
typedef struct rwStreamMatrix RwMatrixChunkInfo;
typedef struct rwStreamMatrix rwStreamMatrix;
struct rwStreamMatrix
{
    RwV3d               right;
    RwV3d               up;
    RwV3d               at;
    RwV3d               pos;
    RwInt32             type;
};


/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

/* Matrix binary format */
extern RwUInt32     RwMatrixStreamGetSize(const RwMatrix * matrix);
extern RwMatrix    *RwMatrixStreamRead(RwStream * stream,
                                       RwMatrix * matrix);
extern const RwMatrix *RwMatrixStreamWrite(const RwMatrix * matrix,
                                           RwStream * stream);
extern RwMatrixChunkInfo *RwMatrixChunkInfoRead(RwStream * stream,
                                                RwMatrixChunkInfo *
                                                matrixChunkInfo,
                                                RwInt32 * bytesRead);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/babinfrm.h ---*/
/****************************************************************************
 Global types
 */

typedef struct rwFrameList rwFrameList;
struct rwFrameList
{
    RwFrame **frames;
    RwInt32 numFrames;
};

/****************************************************************************
 Global Variables 
 */

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Frame binary format */
extern RwInt32 RwFrameRegisterPluginStream(RwUInt32 pluginID,
                                           RwPluginDataChunkReadCallBack readCB,
                                           RwPluginDataChunkWriteCallBack writeCB,
                                           RwPluginDataChunkGetSizeCallBack getSizeCB);
extern RwInt32 RwFrameSetStreamAlwaysCallBack(
                   RwUInt32 pluginID,
                   RwPluginDataChunkAlwaysCallBack alwaysCB);

extern rwFrameList *_rwFrameListInitialize(rwFrameList *frameList, RwFrame *frame);
extern RwBool _rwFrameListFindFrame(const rwFrameList *frameList, const RwFrame *frame, RwInt32 *index);
extern rwFrameList *_rwFrameListDeinitialize(rwFrameList *frameList);
extern RwUInt32 _rwFrameListStreamGetSize(const rwFrameList *frameList);
extern rwFrameList *_rwFrameListStreamRead(RwStream *stream, rwFrameList *fl);
extern const rwFrameList *_rwFrameListStreamWrite(const rwFrameList *frameList, RwStream *stream);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* Comparibility macros */
#define rwFrameListInitialize(frameList,frame) \
       _rwFrameListInitialize(frameList,frame)
#define rwFrameListFindFrame(frameList, frame, index) \
       _rwFrameListFindFrame(frameList, frame, index)
#define rwFrameListDeinitialize(frameList) \
       _rwFrameListDeinitialize(frameList)
#define rwFrameListStreamGetSize(frameList) \
       _rwFrameListStreamGetSize(frameList)
#define rwFrameListStreamRead(stream, fl) \
       _rwFrameListStreamRead(stream, fl)
#define rwFrameListStreamWrite(frameList, stream) \
       _rwFrameListStreamWrite(frameList, stream)


/*--- Automatically derived from: E:/nightly/rwsdk/src/babinary.h ---*/
/****************************************************************************
 Defines
 */

#ifndef rwCHUNKHEADERSIZE
#define rwCHUNKHEADERSIZE (sizeof(RwUInt32)*3)
#endif /* rwCHUNKHEADERSIZE */

/* Compatibility macro */
#define RwStreamWriteInt(_stream, _ints, _numBytes) \
        RwStreamWriteInt32(_stream, _ints, _numBytes)

#define RwStreamReadInt(_stream, _ints, _numBytes) \
        RwStreamReadInt32(_stream, _ints, _numBytes)

#define RwMemLittleEndian(_mem, _size) \
        RwMemLittleEndian32(_mem, _size)

#define RwMemNative(_mem, _size) \
        RwMemNative32(_mem, _size)

/****************************************************************************
 Global Types
 */

typedef struct RwChunkHeaderInfo RwChunkHeaderInfo;
/**
 * \ingroup datatypes
 * \struct RwChunkHeaderInfo
 * Holds data for a chunk header read from a
 * stream with \ref RwStreamReadChunkHeaderInfo. */
struct RwChunkHeaderInfo
{
    RwUInt32 type;      /**< chunk ID - see \ref RwStreamFindChunk */
    RwUInt32 length;    /**< length of the chunk data in bytes */
    RwUInt32 version;   /**< version of the chunk data */
    RwBool isComplex;   /**< Internal Use */
};

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Chunk header stuff */
extern RwBool RwStreamFindChunk(RwStream *stream, RwUInt32 type,
                                RwUInt32 *lengthOut, RwUInt32 *versionOut);

#define RwStreamWriteChunkHeader(stream, type, size) \
    _rwStreamWriteVersionedChunkHeader(stream, type, size, rwLIBRARYCURRENTVERSION)
extern RwStream *_rwStreamWriteVersionedChunkHeader(RwStream *stream,
                                                   RwInt32 type,
                                                   RwInt32 size,
                                                   RwUInt32 version);

extern RwStream *RwStreamWriteReal(RwStream *stream, const RwReal *reals,
                                   RwUInt32 numBytes);
extern RwStream *RwStreamWriteInt32(RwStream *stream, const RwInt32 *ints,
                                    RwUInt32 numBytes);
extern RwStream *RwStreamWriteInt16(RwStream *stream, const RwInt16 *ints,
                                    RwUInt32 numBytes);

extern RwStream *RwStreamReadReal(RwStream *stream, RwReal *reals,
                                  RwUInt32 numBytes);
extern RwStream *RwStreamReadInt32(RwStream *stream, RwInt32 *ints,
                                   RwUInt32 numBytes);
extern RwStream *RwStreamReadInt16(RwStream *stream, RwInt16 *ints,
                                   RwUInt32 numBytes);

/* Binary Portability Functions */
extern void *RwMemLittleEndian16(void *mem, RwUInt32 size);
extern void *RwMemLittleEndian32(void *mem, RwUInt32 size);
extern void *RwMemNative16(void *mem, RwUInt32 size);
extern void *RwMemNative32(void *mem, RwUInt32 size);
extern void *RwMemRealToFloat32(void *mem, RwUInt32 size);
extern void *RwMemFloat32ToReal(void *mem, RwUInt32 size);

extern RwStream *
RwStreamReadChunkHeaderInfo(RwStream *stream, RwChunkHeaderInfo *chunkHeaderInfo);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/babbox.h ---*/
/****************************************************************************
 Global types
 */

typedef struct RwBBox RwBBox;
/**
 * \ingroup datatypes
 * \struct RwBBox
 * This type represents a 3D axis-aligned bounding-box
 * specified by the positions of two corners which lie on a diagonal.
 * Typically used to specify a world bounding-box when the world is created
 * 
 * \param sup Supremum vertex
 * \param inf Infimum vertex
 * 
 * \see RpWorldCreate
 */
struct RwBBox
{
    /* Must be in this order */
    RwV3d sup;   /**< Supremum vertex. */
    RwV3d inf;   /**< Infimum vertex. */
};

#if (!defined(RwBBoxAssign))
#define RwBBoxAssign(_target, _source)            \
    ( *(_target) = *(_source) )
#endif /* (!defined(RwBBoxAssign)) */

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */


extern RwBBox *RwBBoxCalculate(RwBBox *boundBox,
                               const RwV3d *verts,
                               RwInt32 numVerts);
extern RwBBox *RwBBoxInitialize(RwBBox *boundBox,
                                const RwV3d *vertex);
extern RwBBox *RwBBoxAddPoint(RwBBox *boundBox,
                              const RwV3d *vertex);
extern RwBool RwBBoxContainsPoint(const RwBBox *boundBox,
                                  const RwV3d *vertex);


/* LEGACY-SUPPORT macros - remove eventually */
#define _rwBoundingBoxFind(_a, _b, _c)         RwBBoxCalculate(_a, _b, _c)
#define _rwBoundingBoxInitialise(_a, _b)       RwBBoxInitialize(_a, _b)
#define _rwBoundingBoxAddPoint(_a, _b)         RwBBoxAddPoint(_a, _b)
#define _rwBoundingBoxContainsPoint(_a, _b)    RwBBoxContainsPoint(_a, _b) 

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/bacamera.h ---*/

/****************************************************************************
 Defines
 */

/* Type ID */
#define rwCAMERA 4


#if (!(defined(RWDEBUG) || defined(RWSUPPRESSINLINE)))
#define RwCameraGetCurrentCamera() \
    ((RwCamera *) RWSRCGLOBAL(curCamera))
#endif /* (!(defined(RWDEBUG) || defined(RWSUPPRESSINLINE))) */

/****************************************************************************
 Global Types
 */

/**
 * \ingroup datatypes
 * RwCameraClearMode 
 * Camera clear flags */
enum RwCameraClearMode
{
    rwCAMERACLEARIMAGE = 0x1,   /**<Clear the frame buffer */
    rwCAMERACLEARZ = 0x2,       /**<Clear the Z buffer */
    rwCAMERACLEARSTENCIL = 0x4, /**<Clear the stencil buffer 
                                  *(\e supported \e on \e Xbox \e only)*/
    rwCAMERACLEARMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwCameraClearMode RwCameraClearMode;

/**
 * \ingroup datatypes
 * RwCameraProjection 
 * This type represents the options available for 
 * setting the camera projection model, either perspective projection or 
* parallel projection (see API function \ref RwCameraSetProjection)*/
enum RwCameraProjection
{
    rwNACAMERAPROJECTION = 0,   /**<Invalid projection */
    rwPERSPECTIVE = 1,          /**<Perspective projection */
    rwPARALLEL = 2,             /**<Parallel projection */
    rwCAMERAPROJECTIONFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwCameraProjection RwCameraProjection;

/**
 * \ingroup datatypes
 * RwFrustumTestResult 
 * This type represents the results from a 
 * camera frustum test on a given sphere (see API function 
 * \ref RwCameraFrustumTestSphere)*/
enum RwFrustumTestResult
{
    rwSPHEREOUTSIDE = 0,    /**<Outside the frustum */
    rwSPHEREBOUNDARY = 1,   /**<On the boundary of the frustum */
    rwSPHEREINSIDE = 2,     /**<Inside the frustum */
    rwFRUSTUMTESTRESULTFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwFrustumTestResult RwFrustumTestResult;


/**
 * \ingroup datatypes
 * \typedef RwCamera
 * Camera object for rendering a view. 
 * This should be considered an opaque type.
 * Use the RwCamera API functions to access.
 */
typedef struct RwCamera RWALIGN(RwCamera, rwMATRIXALIGNMENT);

/* This allows a world to overload functionality */
typedef RwCamera   *(*RwCameraBeginUpdateFunc) (RwCamera * camera);
typedef RwCamera   *(*RwCameraEndUpdateFunc) (RwCamera * camera);

typedef struct RwFrustumPlane RwFrustumPlane;
/*
 * Structure describing a frustrum plane.
 */
struct RwFrustumPlane
{
        RwPlane             plane;
        RwUInt8             closestX;
        RwUInt8             closestY;
        RwUInt8             closestZ;
        RwUInt8             pad;
};

#if (!defined(DOXYGEN))
struct RwCamera
{
        RwObjectHasFrame    object;

        /* Parallel or perspective projection */
        RwCameraProjection  projectionType;

        /* Start/end update functions */
        RwCameraBeginUpdateFunc beginUpdate;
        RwCameraEndUpdateFunc endUpdate;

        /* The view matrix */
        RwMatrix            viewMatrix;

        /* The cameras image buffer */
        RwRaster           *frameBuffer;

        /* The Z buffer */
        RwRaster           *zBuffer;

        /* Cameras mathmatical characteristics */
        RwV2d               viewWindow;
        RwV2d               recipViewWindow;
        RwV2d               viewOffset;
        RwReal              nearPlane;
        RwReal              farPlane;
        RwReal              fogPlane;

        /* Transformation to turn camera z or 1/z into a Z buffer z */
        RwReal              zScale, zShift;

        /* Render frame counter -> used for the frustum callback stuff */
        RwUInt16            renderFrame;
        RwUInt16            pad;

        /* The clip planes making up the viewing frustum */
        RwFrustumPlane      frustumPlanes[6];
        RwBBox              frustumBoundBox;

        /* Points on the tips of the view frustum */
        RwV3d               frustumCorners[8];
};
#endif /* (!defined(DOXYGEN)) */


/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

    /* Rendering */
extern RwCamera    *RwCameraBeginUpdate(RwCamera * camera);
extern RwCamera    *RwCameraEndUpdate(RwCamera * camera);
#if (defined(RWDEBUG) || defined(RWSUPPRESSINLINE))
extern RwCamera    *RwCameraGetCurrentCamera(void);
#endif /* (defined(RWDEBUG) || defined(RWSUPPRESSINLINE)) */
extern RwCamera    *RwCameraClear(RwCamera * camera, RwRGBA * colour,
                                  RwInt32 clearMode);

/* Displaying results */
extern RwCamera    *RwCameraShowRaster(RwCamera * camera, void *pDev,
                                       RwUInt32 flags);

/* Creation and destruction */
extern RwBool       RwCameraDestroy(RwCamera * camera);
extern RwCamera    *RwCameraCreate(void);
extern RwCamera    *RwCameraClone(RwCamera * camera);

/* Frames */
extern RwCamera    *RwCameraSetFrame(RwCamera * camera, RwFrame * frame);
extern RwFrame     *RwCameraGetFrame(const RwCamera * camera);

/* Rasters */
extern RwCamera    *RwCameraSetRaster(RwCamera * camera,
                                      RwRaster * raster);
extern RwRaster    *RwCameraGetRaster(const RwCamera * camera);
extern RwCamera    *RwCameraSetZRaster(RwCamera * camera,
                                       RwRaster * zRaster);
extern RwRaster    *RwCameraGetZRaster(const RwCamera * camera);

/* Offset */
extern RwCamera    *RwCameraSetViewOffset(RwCamera * camera,
                                          const RwV2d * offset);
extern const RwV2d *RwCameraGetViewOffset(const RwCamera * camera);

/* View window */
extern RwCamera    *RwCameraSetViewWindow(RwCamera * camera,
                                          const RwV2d * viewWindow);
extern const RwV2d *RwCameraGetViewWindow(const RwCamera * camera);

/* Projection */
extern RwCamera    *RwCameraSetProjection(RwCamera * camera,
                                          RwCameraProjection projection);
extern RwCameraProjection RwCameraGetProjection(const RwCamera * camera);
extern RwMatrix    *RwCameraGetViewMatrix(RwCamera * camera);

/* Clip planes */
extern RwCamera    *RwCameraSetNearClipPlane(RwCamera * camera,
                                             RwReal nearClip);
extern RwReal       RwCameraGetNearClipPlane(const RwCamera * camera);
extern RwCamera    *RwCameraSetFarClipPlane(RwCamera * camera,
                                            RwReal farClip);
extern RwReal       RwCameraGetFarClipPlane(const RwCamera * camera);
extern RwCamera    *RwCameraSetFogDistance(RwCamera * camera,
                                           RwReal fogDistance);
extern RwReal       RwCameraGetFogDistance(const RwCamera * camera);

/* Attaching toolkits */
extern RwInt32      RwCameraRegisterPlugin(RwInt32 size,
                                           RwUInt32 pluginID,
                                           RwPluginObjectConstructor
                                           constructCB,
                                           RwPluginObjectDestructor
                                           destructCB,
                                           RwPluginObjectCopy copyCB);
extern RwInt32      RwCameraGetPluginOffset(RwUInt32 pluginID);
extern RwBool       RwCameraValidatePlugins(const RwCamera * camera);

/* Frustum testing */
extern RwFrustumTestResult RwCameraFrustumTestSphere(const RwCamera *
                                                     camera,
                                                     const RwSphere *
                                                     sphere);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/*--- Automatically derived from: E:/nightly/rwsdk/driver/common/barwtyp.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/skyinst.h ---*/

/* Number of qWords in an inst vertex */
#define VERTEXSIZE 4

/* Size of various things for Vu1 dispatch (in qwords) */
#define PROLOGSIZE3D (17+2)
#define PROLOGSIZE2D (5+2)
#define COPYPKTSIZE 3
#define EPILOGSIZE 13

#define MAXVU1BATCHCNT 16

#if (MAXVU1BATCHCNT != 16) && (MAXVU1BATCHCNT != 8)
#error MAXVU1BATCHCNT must be 16 or 8
#endif /* MAXVU1BATCHCNT != 16 */

#if MAXVU1BATCHCNT == 16
#define MAXVU1BATCHCNTSHIFT 4
#define MAXVU1BATCHCNTMASK 0xf
#else /* MAXVU1BATCHCNT == 16 */
#define MAXVU1BATCHCNTSHIFT 3
#define MAXVU1BATCHCNTMASK 0x7
#endif /* MAXVU1BATCHCNT == 16 */

#define VU1DATABLOCKHIGH 0x3f0
#define VU1DATABLOCKLOW 0x3c3
#define VU1WATERMARK_VU1TRANS (MAXVU1BATCHCNT*3*VERTEXSIZE)
#define VU1_VU1TRANS_HBUFSIZE ((VU1LIGHTOFFSET-(MAXVU1BATCHCNT*3*VERTEXSIZE))>>1)
#define VU1WATERMARK_VU1TRANS1 (MAXVU1BATCHCNT*3*VERTEXSIZE)
#define VU1WATERMARK_VU1TRANS2 (VU1WATERMARK_VU1TRANS1+VU1_VU1TRANS_HBUFSIZE)
#define VU1WATERMARK_VU1TRANSL 272
#define VU1WATERMARK_VU1TRANSTS 272
#define VU1LIGHTOFFSET 0x3d0

/* Warning magic numbers ahoy. We transfer batches of up to 64 verts at a time
   This corresponds to 62 triangles, so the sums are abit messy.
 */
#define MAXTSLEN 62
#define MAXTSVERTS (MAXTSLEN+2)
/* WARNING: MAXTSVERTS must be divisible by 4 */

#if 1
/* Support for double buffered dispatch using path 2 */
#define VU1WATERMARK_VU1TRANSLMAP (VU1WATERMARK_VU1TRANSL+(((MAXTSLEN+1)>>1)+2)*3+1)
#define VU1TRANSLMAPGIF 0x3e2
#define VU1WATERMARK_VU1TRANSTSMAP (VU1WATERMARK_VU1TRANSTS+(((MAXTSLEN+1)>>1)+2)*3+1)
#define VU1TRANSTSMAPGIF 0x3e2
#else
/* Support for double buffered dispatch to allow a gloss/env map pass */
/* We halve the size of the output buffer, knowing that the map pass is */
/* 2 qw/v so will fit. This also allows us a buffer containing texture */
/* commands */
#define VU1WATERMARK_VU1TRANSLMAP (VU1WATERMARK_VU1TRANSL+(((MAXTSLEN+1)>>1)+2)*3+1)
#define VU1TRANSLMAPGIF (VU1WATERMARK_VU1TRANSLMAP+(((MAXTSLEN+1)>>1)+2)*2+1)
#define VU1TRANSLMAPSTATEMAIN (VU1WATERMARK_VU1TRANSLMAPGIF+1)
#define VU1TRANSLMAPSTATEMAP (((VU1LIGHTOFFSET-VU1WATERMARK_VU1TRANSLMAPSTATEMAIN+1)>>1)+VU1WATERMARK_VU1TRANSLMAPSTATEMAIN)

#define VU1WATERMARK_VU1TRANSTSMAP (VU1WATERMARK_VU1TRANSTS+(((MAXTSLEN+1)>>1)+2)*3+1)
#define VU1TRANSTSMAPGIF (VU1WATERMARK_VU1TRANSTSMAP+(((MAXTSLEN+1)>>1)+2)*2+1)
#define VU1TRANSTSMAPSTATEMAIN (VU1WATERMARK_VU1TRANSTSMAPGIF+1)
#define VU1TRANSTSMAPSTATEMAP (((VU1LIGHTOFFSET-VU1WATERMARK_VU1TRANSTSMAPSTATEMAIN+1)>>1)+VU1WATERMARK_VU1TRANSTSMAPSTATEMAIN)
#endif

/* Added on 00/07/21 by RP - copied from sky driver then modified for true clip tristrip support */
#define VU1_VU1TRANSTS_HBUFSIZE (((VU1LIGHTOFFSET >> 1 )-VU1WATERMARK_VU1TRANSTS)>>1)
#define VU1WATERMARK_VU1TRANSTS1 VU1WATERMARK_VU1TRANSTS
#define VU1WATERMARK_VU1TRANSTS2 (VU1WATERMARK_VU1TRANSTS1+VU1_VU1TRANSTS_HBUFSIZE)

/* This size used to be defined by the number of RxSkyTransTypeFlags
 * as flags were used directly as an index into the array. However,
 * this is no longer necessarily the case (since there are so many
 * flags these days and we have packed, multi-purpose transforms, and
 * different plugins use different subsets of flag combinations, etc).
 * This size may change or become obsolete (used only by the driver). */
#define VU1CODEARRAYSIZE 32

/**
 * \ingroup corep2sky2
 * \ref RxSkyTransTypeFlags
 * Flags specifying the desired behavior for the current VU1 transform.
 */
enum RxSkyTransTypeFlags
{
    rxSKYTRANSTYPENATRANSTYPE = 0,

    /* These correspond to bits in skyTransType.
     * They are used in the driver to select transforms from the VU1CodeArray.
     * The flags use to be used directly as the index into this array, but
     * this is no longer necessarily so (we have combined many permutations
     * into single, multi-purpose transforms and there are just too many flags
     * these days) index is specified separately (see \ref RxPS2DMASessionRecord) */
    rxSKYTRANSTYPEFOG  = 1,  /**< The transform should fog */
    rxSKYTRANSTYPECLIP = 2,  /**< The transform should clip (see \ref RpSkySelectTrueTSClipper) */
    rxSKYTRANSTYPELIST = 4,  /**< The transform should process triangles as trilists not tristrips */
    rxSKYTRANSTYPEISO  = 8,  /**< The transform should do orthogonal, not perspective, projection */
    rxSKYTRANSTYPELINE = 16, /**< The transform should process input data as lines, not triangles or points */
    rxSKYTRANSTYPECULL = 32, /**< The transform should do culling based on culling renderstate
                              *   (as opposed to always drawing front and back) */

    rxSKYTRANSTYPEFLAGSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};

#define TRANSFOG  rxSKYTRANSTYPEFOG
#define TRANSCLIP rxSKYTRANSTYPECLIP
#define TRANSLIST rxSKYTRANSTYPELIST
#define TRANSISO  rxSKYTRANSTYPEISO
#define TRANSLINE rxSKYTRANSTYPELINE
#define TRANSCULL rxSKYTRANSTYPECULL
/* For documentation - remember not to test flags against these! */
#define TRANSNFOG  0
#define TRANSNCL   0
#define TRANSSTRIP 0
#define TRANSPER   0
#define TRANSTRI   0

/**
 * \ingroup corep2sky2
 * \typedef RxSkyTransTypeFlags
 * Typedef for the RxSkyTransTypeFlags enum
 */
typedef enum RxSkyTransTypeFlags RxSkyTransTypeFlags;


/****************************************************************************
 Global variables
 */

extern RwUInt8 skyTransType;

extern const void *skyUploadedCode;
extern void* skyVU1Transforms[VU1CODEARRAYSIZE] __attribute__ ((aligned(64)));

extern u_long128 nullLightCall;
extern u_long128 dma1Header128;
extern u_long128 maskCmd128;
extern u_long128 unmaskCmd128;
extern u_long128 runCmd128;
extern u_long128 contCmd128;
extern u_long128 dma1Ret128;
extern u_long128 gifTagPrim128;
extern u_long128 surfLightCoeffs;
extern u_long128 nullLightBlock[2];
extern u_long128 skyClipVect1;
extern u_long128 skyClipVect2;
extern u_long128 skyCClipVect1;
extern u_long128 skyCClipVect2;
extern RwUInt32  skyUserSwitch1;
extern RwUInt32  skyUserSwitch2;
extern RwBool    skyTSClipperMode;
extern RwBool    skyTLClipperMode;


#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

extern RwBool openVU1SetupPkt(RwUInt32 primCode, const void *code, const RwMatrix *matrix,
                              const u_long128 *lightPkt, RwUInt32 lightPktLen);


#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/basky.h ---*/
#ifndef _RW_EETYPES_H
#define _RW_EETYPES_H
#include <eetypes.h>
#endif /* _RW_EETYPES_H */

/* This chooses a simpler texture cache and parallel upload. Its a bit ugly */
/* to have two versions of the code present, but this will let source */
/* licensees choose the one they want */
#define ASYNCTEXTURES


#ifndef __MWERKS__

/* The following assembler burst let me build a 128 bit from 2x 64 bit */
#define MAKE128(RES, MSB, LSB) \
        __asm__ volatile ( "pcpyld %0, %1, %2" : "=r" (RES) : "r" (MSB), "r" (LSB))

#else /* ! __MWERKS__ */

/* The following assembler burst let me build a 128 bit from 2x 64 bit */
#define MAKE128(RES, MSB, LSB) \
do    \
{     \
    u_long128 ___ltmp;  \
    __asm__ volatile ( "pcpyld %0, %1, %2" : "=r" (___ltmp) : "r" (MSB), "r" (LSB));  \
    RES = ___ltmp; \
} while (0)

#endif /* ! __MWERKS__ */


/* callback type used to change the raster at the last minute
 * (based on plugin data) or just snoop uploaded rasters. */
typedef void (*SkyCacheSnoopCallBack)(RwRaster **);



#ifdef SCE_11
#define SCESYNCDCACHEROUNDUP(x) (x)
#else
#define SCESYNCDCACHEROUNDUP(x) ((void *)(((RwUInt32)(x)) + 127 ))
#endif

typedef struct _SkyCameraExt _SkyCameraExt;
struct _SkyCameraExt
{
    RwV3d          largeFrustumVerts[8];                /**< Internal use */
    RwFrustumPlane largeFrustumPlanes[6];               /**< Internal use */
};

#define RASTEREXTFROMRASTERCONST(raster) \
    ((const _SkyRasterExt *)(((const RwUInt8 *)(raster)) + skyRasterExt))
#define CAMERAEXTFROMCAMERACONST(camera) \
    ((const _SkyCameraExt *)(((const RwUInt8 *)(camera)) + skyCameraExt))

#define RASTEREXTFROMRASTER(raster) \
    ((_SkyRasterExt *)(((RwUInt8 *)(raster)) + skyRasterExt))
#define CAMERAEXTFROMCAMERA(camera) \
    ((_SkyCameraExt *)(((RwUInt8 *)(camera)) + skyCameraExt))


#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/****************************************************************************
 Global Variables
 */

extern RwInt32 skyRasterExt;
extern RwInt32 skyCameraExt;
extern int skyFrameBit;
extern long skyZbuf_1;
extern long skyFrame_1;
extern long skyTest_1;
extern long skyXyoffset_1;
extern long skyFogcol;
extern long skyClamp_1;
extern long skyTex1_1;
extern long skyAlpha_1;

extern long skyPrim_State;
extern RwRaster *skyTextureRaster;
extern RwBool skyAlphaTex;
extern RwBool skyVertexAlpha;

extern RwCullMode gSkyCullState;

extern RwBool cacheOpened;
extern RwBool needCache;

extern RwUInt32 skyFSAA0VisibleWidth;
extern RwUInt32 skyFSAA0RenderWidth;
extern RwUInt32 skyFSAA0RenderHeight;
extern RwUInt32 skyFSAA0FrameCount;

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */


/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */


extern RwInt32 _rwSkyFindMSB(RwUInt32 nInt);
extern RwBool _rwSkySetRenderState(RwRenderState nState, void *param);
extern RwBool _rwSkyFSAAMode0SetVisibleWidth(RwUInt32 width);

extern RwBool RpSkySuspend(void);
extern RwBool RpSkyResume(void);

extern RwBool _skyRasterGetTwiddling(RwRaster *ras);
extern RwRaster *_skyRasterSetTwiddling(RwRaster *ras, RwBool twiddling);

extern void			_rpSkyFrameBufferRastersUpdate(void);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* LEGACY-SUPPORT macros */
#define skyFSAAMode0SetVisibleWidth(width)  \
            _rwSkyFSAAMode0SetVisibleWidth(width)


#if (!defined(RXPIPELINE))
#define RXPIPELINE
#endif                        /* (!defined(RXPIPELINE)) */


/*--- Automatically derived from: E:/nightly/rwsdk/driver/sky2/texcache.h ---*/

/* callback type used to signal a raster is needed and is not in cache */
typedef void (*SkyCacheCallBack)(RwRaster *, RwBool);


#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */


#ifdef ASYNCTEXTURES
extern void     RpSkyTexCacheAccessSpeculate(RwRaster *raster);
#else /* ASYNCTEXTURES */
#define         RpSkyTexCacheAccessSpeculate(raster)
#endif /* ASYNCTEXTURES */
extern RwBool   RpSkyTexCacheAccessRaster(RwRaster *raster, RwBool useContext2);
extern void     RpSkyTexCacheReleaseRaster(RwRaster *rpRas);
extern RwBool   RpSkyTexCacheRasterLock(RwRaster *raster, RwBool bLocked);
#ifdef ASYNCTEXTURES
extern void     RpSkyTexCacheRasterUnlockAll(void);
#endif /* ASYNCTEXTURES */
extern void     RpSkyTexCacheFlush(void);
extern void     RpSkyTexCacheRestore(void);

/* Theses were the old names which were used when this wasn't exposed */
#define skyTexCacheAccessRaster  RpSkyTexCacheAccessRaster
#define skyTexCacheReleaseRaster RpSkyTexCacheReleaseRaster
#define skyTexCacheRasterLock    RpSkyTexCacheRasterLock
#define skyTexCacheFlush         RpSkyTexCacheFlush
#define skyTexCacheRestore       RpSkyTexCacheRestore

/* This function remains for backwards compatability. It doesn't do what you
   might think */
extern RwBool   RpSkyTextureCacheSetState(RwInt32 nFlags);

/* This is still considered to be a non-firstclass function */
extern void     skyPrepareUploadRaster(RwRaster *raster);

/* A cache overload API is provided to enable wholesale replacement of the
  cache. This is used some where the application has special requirements. */
#ifdef ASYNCTEXTURES
extern RwBool   RpSkyTexCacheDisable(RwBool disable);
#else /* ASYNCTEXTURES */
extern RwBool   skyTexCacheDisable(void);
#endif /* ASYNCTEXTURES */
extern RwUInt32 RpSkyTexGetStartAddress(void);
extern RwUInt32 RpSkyTexGetSize(void);
extern RwBool   RpSkyTexCacheSetCallBack(SkyCacheCallBack fpCacheCB);
extern RwUInt32 RpSkyTexCacheRasterGetAddr(RwRaster *r);
extern RwRaster *RpSkyTexSetTex0(RwRaster *r, RwUInt32 msb, RwUInt32 lsb);
extern RwRaster *RpSkyTexGetTex0(RwRaster *r, RwUInt32 *msb, RwUInt32 *lsb);
extern RwRaster *RpSkyTexSetMiptbp1(RwRaster *r, RwUInt32 msb, RwUInt32 lsb);
extern RwRaster *RpSkyTexGetMiptbp1(RwRaster *r, RwUInt32 *msb, RwUInt32 *lsb);
extern RwRaster *RpSkyTexSetMiptbp12(RwRaster *r, RwUInt32 msb1, RwUInt32 lsb1,
                                     RwUInt32 msb2, RwUInt32 lsb2);
extern RwRaster *RpSkyTexGetMiptbp12(RwRaster *r, RwUInt32 *msb1,
                                     RwUInt32 *lsb1, RwUInt32 *msb2,
                                     RwUInt32 *lsb2);
extern RwRaster *RpSkyTexCacheValidateRaster(RwRaster *r, RwBool valid);
extern RwBool   RpSkyUploadPixelData(RwUInt32 pixelWidth,
                                   RwUInt32 pixelHeight,
                                   RwUInt8 *srcAddress,
                                   RwUInt32 dstAddress,
                                   RwUInt32 dstWidthBy64,
                                   RwUInt32 bitsPerPixel,
                                   RwUInt32 pixelFormat,
                                   RwUInt32 srcStride);
/* Provided to allow faster upload of textures of type "flags&1" */
extern RwRaster *RpSkyTexCacheUploadRaster(RwRaster *r, RwUInt32 dstAddress);

#ifdef ASYNCTEXTURES
#define skyTexCacheDisable()      RpSkyTexCacheDisable(TRUE)
#endif /* ASYNCTEXTURES */
#define skyTexGetStartAddress     RpSkyTexGetStartAddress
#define skyTexCacheSetCallback    RpSkyTexCacheSetCallback
#define RpSkyTexCacheSetCallback  RpSkyTexCacheSetCallBack
#define skyTexCacheRasterGetAddr  RpSkyTexCacheRasterGetAddr
#define skyTexSetTex0             RpSkyTexSetTex0
#define skyTexGetTex0             RpSkyTexGetTex0
#define skyTexSetMiptbp1          RpSkyTexSetMiptbp1
#define skyTexGetMiptbp1          RpSkyTexGetMiptbp1
#define skyTexCacheValidateRaster RpSkyTexCacheValidateRaster
#define skyUploadPixelData        RpSkyUploadPixelData

/* You shouldn't have to access this variable */
extern RwUInt32 skyGNumTexMemBlocks;

#ifndef ASYNCTEXTURES
extern RwBool   skyTexCacheSetSnoopCallback(SkyCacheSnoopCallBack fpCacheCB);
#endif /* ASYNCTEXTURES */


#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

#if (!defined(RXPIPELINE))
#define RXPIPELINE
#endif /* (!defined(RXPIPELINE)) */

/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/sky2/exports.h ---*/

/*--- Automatically derived from: E:/nightly/rwsdk/src/pipe/p2/bapipe.h ---*/

struct rwPipeGlobals
{
    RxRenderStateVector  defaultRenderState;
    RwLinkList           allPipelines;         /* Unused as of yet, meant to be used to keep track of all
                                                  created pipelines (for CBs and maybe cleanup) */

    /* NOTE: Rw and RpWorld PowerPipe globals kept together for simplicity */

    /* The current default pipelines (used if pipe == NULL for an object) */
    RxPipeline          *currentAtomicPipeline;
    RxPipeline          *currentWorldSectorPipeline;
    RxPipeline          *currentMaterialPipeline;
    /* Generic C-based pipes that run on all platforms
     * - these are set as the current pipes at startup unless
     *   platform-specific pipes (below) are created */
    RxPipeline          *genericAtomicPipeline;
    RxPipeline          *genericWorldSectorPipeline;
    RxPipeline          *genericMaterialPipeline;
    /* Platforms that have their own non-generic pipelines
     * (OPENGL, D3D7, SKY2, KAMUI2, DOLPHIN) put them here: */
    RxPipeline          *platformAtomicPipeline;
    RxPipeline          *platformWorldSectorPipeline;
    RxPipeline          *platformMaterialPipeline;
#if (defined(SKY2_DRVMODEL_H))
    /* We have extra flavours of pipe under SKY2
     *  - see RpWorldSectorSkyGetPS2AllPipeline, etc */
    RxPipeline          *ps2AllAtomicPipeline;
    RxPipeline          *vanillaAtomicPipeline;
    RxPipeline          *allInOneAtomicPipeline;
    RxPipeline          *ps2AllWorldSectorPipeline;
    RxPipeline          *vanillaWorldSectorPipeline;
    RxPipeline          *allInOneWorldSectorPipeline;
    RxPipeline          *ps2AllMatMaterialPipeline;
    /* This one's the default, used by PS2All for materials with NULL pipes: */
    RxPipeline          *currentPS2AllMatMaterialPipeline;
#endif /* (SKY2_DRVMODEL_H) */
    
};

typedef struct rwPipeGlobals rwPipeGlobals;

#define RXPIPELINEGLOBAL(var) (RWPLUGINOFFSET(rwPipeGlobals, RwEngineInstance, _rxPipelineGlobalsOffset)->var)

#ifdef    __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RwInt32      _rxPipelineGlobalsOffset;

#ifdef    __cplusplus
}
#endif /* __cplusplus */


/*--- Automatically derived from: E:/nightly/rwsdk/src/babincam.h ---*/
/****************************************************************************
 Global types
 */

/* Camera stream format */
typedef struct rwStreamCamera RwCameraChunkInfo;
typedef struct rwStreamCamera rwStreamCamera;
struct rwStreamCamera
{
    RwV2d viewWindow;
    RwV2d viewOffset;
    RwReal nearPlane, farPlane;
    RwReal fogPlane;
    RwUInt32 projection;
};

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

/* Camera binary format */
extern RwInt32 RwCameraRegisterPluginStream(RwUInt32 pluginID,
                                            RwPluginDataChunkReadCallBack readCB,
                                            RwPluginDataChunkWriteCallBack writeCB,
                                            RwPluginDataChunkGetSizeCallBack getSizeCB);
extern RwInt32 RwCameraSetStreamAlwaysCallBack(
                   RwUInt32 pluginID,
                   RwPluginDataChunkAlwaysCallBack alwaysCB);
extern RwUInt32 RwCameraStreamGetSize(const RwCamera *camera);
extern RwCamera *RwCameraStreamRead(RwStream *stream);
extern const RwCamera *RwCameraStreamWrite(const RwCamera *camera,
                                           RwStream *stream);
extern RwCameraChunkInfo * RwCameraChunkInfoRead(RwStream *stream,
                                                 RwCameraChunkInfo *cameraChunkInfo,
                                                 RwInt32 *bytesRead);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

#endif /* RWCORE_H */
